РЕДАКТИРОВАТЬ: Извините, я не заметил тег Python-3 во времени, это все то же самое, за исключением того, что при наследовании вы бы вызывали super().__init__
вместо Frame.__init__
напрямую.Это сделало бы его более похожим на Py3.Тем не менее, это все равно должно работать.
Странно, но нажатие menu.config до функции run
сработало для меня - хотя, похоже, все должно работать так, как вы это сделали.
def main():
root=tk.Tk()
ug=UserGui(root)
root.config(menu=ug.fileMenu)
root.mainloop()
if __name__ == '__main__':
main()
В противном случае есть некоторые вещи, над которыми вы можете работать, чтобы сделать их более понятными и читаемыми.Так я обычно делаю GUI.Идея состоит в том, чтобы разделить GUI на Frames
, которые затем делают схожие вещи.Т.е. ваше приложение могло бы иметь левый и правый фрейм, где правый фрейм содержал бы текстовое поле, а левый фрейм фактически имел бы 2 субкадра - один для имен и выпадающих меню, а другой для кнопок.Таким образом, каждая отдельная функциональность обрабатывается самими фреймами, и не все в одном гигантском классе, элементы в этих фреймах размещаются относительно самой сетки фрейма, а все фреймы размещаются в сетке мэйнфрейма.Это позволяет вам разбивать большой объем кода на модули и помогает с удобством сопровождения.
Подкадры генерируют «глобальные» события (события, мешающие другим кадрам), распространяя их через MainFrame, поэтому все они переносятself.parent - их родительский фрейм, а self.root - основной фрейм.MainFrame также является фреймом, в который я хотел бы поместить что-то вроде self.data
, которое само по себе является классом (за пределами Tkinter), который обрабатывает весь ввод / вывод данных и логику, чтобы вы не загромождали логику кода GUI.с расчетами данных и логикой.В идеале класс Data будет обрабатывать ошибки данных, а GUI только тогда должен будет обрабатывать любые ошибки в логике (такие как выбор двух невозможных для объединения параметров из раскрывающихся меню.
from tkinter import *
from tkinter import ttk
class SubFrame(Frame):
def __init__(self, parent, text="Top Right"):
Frame.__init__(self)
self.pack()
self.parent = parent
self.root = parent.root
self.label=Label(self, text=text).pack()
class RightFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, relief=RAISED, borderwidth=1)
self.pack(side=RIGHT, fill=BOTH, expand=1)
self.root = parent
self.label = Label(self, text="Right Frame").pack()
class LeftFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, relief=RAISED, borderwidth=1)
self.pack(side=LEFT, fill=BOTH, expand=1)
self.root = parent
self.label = Label(self, text="Left Frame").pack()
#again Frames which would have a parent class RightFrame and root MainFrame
self.subFrame1 = SubFrame(self)
self.subFrame2 = SubFrame(self, text="Top Right SubFrame 2")
class MainFrame(Tk):
def __init__(self):
Tk.__init__(self)
self.geometry("1100x600")
self.title("Working Example")
self.leftFrame = LeftFrame(self)
self.rightFrame = RightFrame(self)
#self.data = MagicalDataHandlingClass()
def run():
app = MainFrame()
app.mainloop()
EDIT ответ на комментарии, которые слишком длинны, чтобы уместиться
Вызов Frame.__init__(...)
сделан потому, что определение класса выглядит как class LeftFrame(Frame)
. Обычно для объявления класса то, что вы пишете, это просто class LeftFrame
.Когда вы добавляете бит в ()
, то, что происходит, называется наследованием. Когда вы наследуете от класса (называемого родительским), ваш класс (называемый дочерним) наследует все методы и атрибуты родительского элемента. Но так же, как вы должныинициализируйте ваш класс, чтобы получить объект, то есть lf = LeftFrame(...)
родительский класс тоже должен быть инициализирован. В Python эта инициализация выполняется путем вызова специальной функции dunder __init__(...)
. Так что вызов Frame.__init__(...)
происходит потому, что вам нужно сказатьродительский класс, каковы все значения, необходимые для правильной работы.В Python 3, однако, рекомендуется вместоДля создания экземпляра родительского элемента по имени вы используете функцию super
, например super().__init__(....)
.Это происходит по многим сложным причинам, по большинству из которых вам, вероятно, пока не придется беспокоиться (например, что если вы наследуете от нескольких классов одновременно, что если вы наследуете от класса, унаследованного отдругой и т.д ...).Я бы не стал чувствовать себя ошеломленным, понимая всю мощь super()
, если вы только начинаете, потому что в 99% случаев в Python 3 просто выполнение super().__init__(...)
будет делать именно то, что вы хотите, даже если вы не понимаете,Если вам хочется взбодриться над головой У Раймонда Хеттингера есть хорошее описание Super is Super, и почему именно он намного лучше старого.