#python #python-3.x #python-2.7 #user-interface #tkinter
Вопрос:
У меня есть основной файл с графической формой Tkinter (классическое окно), который называется, например A.py
, и main=Tk()
. Кроме того, как я могу вспомнить B.py файл, если он находится во вложенной папке основного проекта?
Нажав, например, на пункт в меню панели, такой как «Открыть форму B», как я могу открыть графическую форму (классическое окно) `B.py? ВАЖНО: без консоли вывода, но только в графической форме P. S: пожалуйста, не используйте «self». Спасибо
ФАЙЛ A.PY: ОСНОВНЫЕ
from tkinter import *
from tkinter import ttk
import tkinter as tk
main=Tk()
main.title("xxxxxx")
main.geometry("750x750")
main.configure(bg='#282828')
#Bar Menù (no need to write all the code of bar menu)
filemenu.add_command (label = 'Open form B', command = ????)
ФАЙЛ B.PY: ВТОРИЧНОЕ
from tkinter import *
from tkinter import ttk
import tkinter as tk
secondary=Tk()
secondary.title("yyyyyyy")
secondary.geometry("750x750")
secondary.configure(bg='#282828')
РЕДАКТИРОВАТЬ (код обновлен, но я не знаю, правильно ли это):
ФАЙЛ A.PY: ОСНОВНЫЕ
from tkinter import *
from tkinter import ttk
import tkinter as tk
from b import *
main=Tk()
main.title("xxxxxx")
main.geometry("750x750")
main.configure(bg='#282828')
#Bar Menù (no need to write all the code of bar menu)
filemenu.add_command (label = 'Open form B', command = b.draw_graph)
ФАЙЛ B.PY: ВТОРИЧНОЕ
from tkinter import *
from tkinter import ttk
import tkinter as tk
from b import *
def draw_graph():
secondary=Toplevel("home/mypc/Destkop/Folder1/Folder2/B.py/secondary)
secondary.title("yyyyyyy")
secondary.geometry("750x750")
secondary.configure(bg='#282828')
ЗАГРУЗКА 2 (только B.py):
from tkinter import *
from tkinter import ttk
import tkinter as tk
def draw_graph():
global secondary=Toplevel()
secondary.title("yyyyyyy")
secondary.geometry("750x750")
secondary.configure(bg='#282828')
#combobox
comboboxx=["xxxxxx", "xxxxx"]
combobox=ttk.Combobox(secondary, width=19)
combobox.place(x=6, y=12)
combobox.config(values=comboboxx)
combobox.set("Scegli")
# I only wrote a small part of the code, showing the combobox.
# But the code is very long. I would not like to put everything
# in the function (if that is possible)
Ошибка: поле ввода=ttk.Поле ввода(вторичное, ширина=19)
Ошибка имени: имя «вторичное» не определено
Комментарии:
1. Под «графической формой» вы точно подразумеваете окно? Рекомендуемая причина для открытия дополнительных окон
tkinter
заключается в созданииToplevel
виджетов, а неTk()
в многократном вызове.2. @martineau Да, верно, я имею в виду классическое окно. Не могли бы вы показать мне ответ, пожалуйста? Я новичок в Python. Спасибо 🙂
3. если вы будете хранить код в функциях, то сможете решить, когда запускать их после
importing
. И функции могут получитьparent
в качестве аргумента , поэтому при импорте вы можете использоватьToplevel()
какparent
, а при непосредственном запуске кода вы можете использоватьTk()
какparent
4. если вы хотите получить лучший ответ, вам нужно создать лучший вопрос — не ожидайте, что мы напишем весь код для вас. Вы могли бы поместить минимальный рабочий код, который мы могли бы просто скопировать и изменить для создания решения.
5. @furas Разделил ответ на два комментария. Конечно, ты прав. Но, будучи очень простым вопросом, я подумал, что предоставленных мной данных достаточно, например main = Tk (). Мне также нужно было написать main.title («название»), main.geometry («750×750») и main.configure (bg = ‘# 282828’)? То же самое для второго окна? Они бесполезны. Я просто написал необходимые данные, т. е. main.title («заголовок») для первого окна и secondary = Tk () для второго окна, добавив также имена файлов py.
Ответ №1:
Код в b.py
вы должны хранить в функциях, чтобы контролировать, когда его запускать
b.py
import tkinter as tk # PEP8: `import *` is not preferred
# in file `b.py` you don't need `import b` nor `from b import *`
def draw_graph():
win = tk.Toplevel()
label = tk.Label(win, text="GRAPH")
label.pack()
а потом можно import b
и в жопу command=b.draw_graph
main.py
(Я использую Button
для создания минимального рабочего кода, чтобы каждый мог просто скопировать и запустить его)
import tkinter as tk # PEP8: `import *` is not preferred
import b # PEP8: `import *` is not preferred
def main():
root = tk.Tk() # PEP8: spaces around `=` when assigning to variable
# ... code ...
#filemenu.add_command(label='Open form A1', command=b.draw_graph) # PEP8: `=` without spaces when assigning arguments
# to use `b.draw_graph` you have to use `import b`, not `from b import *`
button = tk.Button(root, text="Open form A1", command=b.draw_graph)
button.pack()
root.mainloop()
if __name__ == '__main__':
main()
Если бы вы использовали
from b import *
тогда вам пришлось бы использовать command=draw_graph
вместо command=b.draw_graph
Если у вас есть b.py
подпапка с именем other
, то вы можете сделать
from other import b
и все еще пользуюсь command=b.draw_graph
или
import other.b
и тогда вам придется использовать command=other.b.draw_graph
PEP 8 — Руководство по стилю для кода на Python
Редактировать:
Я уже писал, как использовать код из подпапки, но я повторяю
если у вас есть Folder1/main.py
, а Folder1/Folder2/B.py
затем в main.py
вас нужно только
from Folder2 import B
command=B.draw_graph
или
import Folder2.B
command=Folder2.B.draw_graph
(если файл имеет имя в верхнем регистре B
, то модуль также имеет имя в верхнем регистре B
)
Он должен работать без добавления папки sys.path
и без добавления файла Folder2/__init__.py
Если у вас будет Folde1/main.py
и Folder1/Folder2/Folder3/B.py
тогда вам нужно
from Folder2.Folder3 import B
command=B.draw_graph
или
import Folder2.Folder3.B
command=Folder2.Folder3.B.draw_graph
В конце концов, вы можете добавить текущую папку sys.path
перед импортом
import os
import sys
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
from Folder2 import B
#import Folder2.B
и это будет работать также, когда вы запускаете код из другой папки
(другое Current Working Directory
— проверка print(os.getcwd())
)
Например
cd ..
python Folder1/main.py
или
cd /
python /home/mypc/Destkop/Folder1/main.py
Комментарии:
1. Большое спасибо. Спасибо 🙂 Прекрасный ответ. Но вы забыли написать, как загрузить B.py если он находится во вложенной папке. Например, если main.py находится в папке home / mypc / Destkop / Folder1 и B.py находится в домашней / mypc / Destkop / Папке 1 / Папке 2 / B.py. Как я могу это получить? Однако завтра я хорошо перепишу вопрос. Я пишу старый исходный код, а затем отдельно добавляю UPLOAD 1, чтобы читатели поняли. Тогда, конечно, я голосую за ваш любезный ответ 🙂 Я буду признателен, если вы измените свой ответ на проблему с подпапками. Спасибо, увидимся завтра
2. Я уже написал это —
from Folder2 import B
илиimport Folder2.B
— но я использовал имяother
. Я только не показал, как добавитьFolder1
sys.path
, чтобы убедиться, что он найдетFolder2
, когда вы будете запускать код из другой папки, чемFolder1
— iepython Folder1/main.py
вместоpython main.py
3. Ты написал мне прекрасный ответ. Это похоже на книгу. Хорошо! Искренние поздравления! Теперь я редактирую свой вопрос, как мы говорили вчера. Несколько минут. Однако я получаю ошибку. Я сделал, как вы сказали, но я понял следующее: импорт модуля b не является основанием для: Нет модуля с именем «b». Я пробовал как с импортом b, так и с импортом b *. Я также изменил команду = b.draw_graph или даже команду = draw_graph. Я сделал в точности так, как вы мне написали, как в A.py и B.py. Почему эта ошибка? Спасибо
4. если у вас имя
B.py
файла в верхнем регистреB
, то вы должныimport B
использовать верхний регистрB
— я также написал это в ответе.5. почему вы используете
a = tk.Toplevel ()
вместоwin = tk.Toplevel ()
. Вы ввелиCombobox(win, ...)
в действие функцию? если у вас есть внешняя функция, то она выполняется при импорте файла — поэтому она выполняется перед созданиемwin = ...
. Как я уже говорил в начале — вы должны хранить ВЕСЬ КОД в функциях. ИCombobox(win, ...)
должно быть послеwin = ...
КСТАТИ: в моем коде я создаюLabel(win,...)
и делаю это внутриdraw_graph
, послеwin = ...
— это не может быть снаружиdraw_graph
Ответ №2:
Используйте функцию верхнего уровня()
- сделайте первый файл таким, как вы хотите, как имя, и напишите этот код (a.py для примера)
from tkinter import *
from tkinter.ttk import *
from b import *
class app:
def __init__(self, root):
self.root = root
self.menu_bar()
self.root.mainloop()
def menu_bar(self):
self.app = app1()
self.menubar = Menu(self.root)
self.filemenu = Menu(self.menubar, tearoff=0)
self.filemenu.add_command(
label="Open A1", command=lambda: self.app.second(self.root))
self.filemenu.add_separator()
self.filemenu.add_command(label="Exit", command=self.root.quit())
self.menubar.add_cascade(label="File", menu=self.filemenu)
self.root.config(menu=self.menubar)
if __name__ == "__main__":
app(Tk())
- и во втором файле убедитесь, что его имя, как вы пишете в a.py(из импорта имени файла *) (b.py для примера) и напишите так
class app1:
def second(self, root):
self.root = Toplevel(root)
Label(self.root, text="A2").pack(padx=20, pady=20)
это должно решить вашу проблему