Ниже приведена общая структура моей типичной программы Python tkinter.
def funA():
def funA1():
def funA12():
# stuff
def funA2():
# stuff
def funB():
def funB1():
# stuff
def funB2():
# stuff
def funC():
def funC1():
# stuff
def funC2():
# stuff
root = tk.Tk()
button1 = tk.Button(root, command=funA)
button1.pack()
button2 = tk.Button(root, command=funB)
button2.pack()
button3 = tk.Button(root, command=funC)
button3.pack()
funA
funB
и funC
вызовет другие Toplevel
окна с виджетами, когда пользователь нажмет кнопку 1, 2, 3.
Мне интересно, если это правильный способ написания программы Python Tkinter? Конечно, это сработает, даже если я напишу так, но лучше ли? Звучит глупо, но когда я вижу коды, написанные другими людьми, их код не перепутается с кучей функций, и в основном у них есть классы.
Есть ли какая-то конкретная структура, которой мы должны следовать в качестве хорошей практики? Как я должен планировать, прежде чем начать писать программу на Python?
Я знаю, что нет лучшей вещи в программировании, и я не прошу об этом. Я просто хочу несколько советов и объяснений, чтобы держать меня в правильном направлении, поскольку я изучаю Python самостоятельно.
Ответы:
Я защищаю объектно-ориентированный подход. Это шаблон, с которого я начинаю:
Важные вещи, на которые стоит обратить внимание:
Я не использую импорт подстановочных знаков. Я импортирую пакет как «tk», который требует, чтобы я поставил перед всеми командами префикс
tk.
. Это предотвращает глобальное загрязнение пространства имен, а также делает код совершенно очевидным, когда вы используете классы Tkinter, классы ttk или некоторые другие.Основное приложение - это класс . Это дает вам личное пространство имен для всех ваших обратных вызовов и частных функций, и, как правило, упрощает организацию вашего кода. В процедурном стиле вы должны кодировать сверху вниз, определять функции перед их использованием и т. Д. С помощью этого метода вы этого не делаете, поскольку вы фактически не создаете главное окно до самого последнего шага. Я предпочитаю наследовать
tk.Frame
только потому, что обычно начинаю с создания фрейма, но это ни в коем случае не является необходимым.Если в вашем приложении есть дополнительные окна верхнего уровня, я рекомендую сделать каждый из них отдельным классом, унаследованным от
tk.Toplevel
. Это дает вам все те же преимущества, что и упомянутые выше: окна являются атомарными, у них есть собственное пространство имен, а код хорошо организован. Кроме того, он позволяет легко помещать каждый в отдельный модуль, когда код начинает увеличиваться.Наконец, вы можете рассмотреть возможность использования классов для каждой основной части вашего интерфейса. Например, если вы создаете приложение с панелью инструментов, панелью навигации, строкой состояния и основной областью, вы можете создать каждый из этих классов. Это делает ваш основной код довольно маленьким и легким для понимания:
Поскольку все эти экземпляры имеют общего родителя, родительский элемент фактически становится частью «контроллера» в архитектуре модель-представление-контроллер. Так, например, главное окно может поместить что-то в строку состояния, вызвав вызов
self.parent.statusbar.set("Hello, world")
. Это позволяет вам определить простой интерфейс между компонентами, помогая поддерживать связь с минимальным.источник
parent
, если вы не собираетесь использовать ее позже. Я не сохранил его, потому что ни один код в моем примере не требовал его сохранения.Помещение каждого из ваших окон верхнего уровня в отдельный класс обеспечивает повторное использование кода и лучшую организацию кода. Все кнопки и соответствующие методы, присутствующие в окне, должны быть определены внутри этого класса. Вот пример (взятый отсюда ):
Также см:
Надеюсь, это поможет.
источник
Это не плохая структура; это будет работать просто отлично. Тем не менее, вам нужно иметь функции в функции для выполнения команд, когда кто-то нажимает на кнопку или что-то
Так что вы могли бы написать классы для них, а затем иметь методы в классе, которые обрабатывают команды для нажатий кнопок и тому подобное.
Вот пример:
Обычно программы с несколькими окнами представляют собой несколько больших классов, и во
__init__
всех записях создаются метки и т. Д., А затем каждый метод обрабатывает события нажатия кнопки.На самом деле не существует правильного способа сделать это, что бы ни работало для вас и выполняло работу, пока она читаема, и вы можете легко объяснить это, потому что, если вы не можете легко объяснить свою программу, возможно, есть лучший способ сделать это. ,
Взгляните на мышление в Tkinter .
источник
ООП должен быть подходом и
frame
должен быть переменной класса вместо переменной экземпляра .Ссылка: http://www.python-course.eu/tkinter_buttons.php
источник
TKinter
на Python 2. Я бы порекомендовал использоватьtkinter
для Python 3. Я бы также поместил последние три строки кода вmain()
функцию и вызвал ее в конце программы. Я бы определенно избегал его использования,from module_name import *
поскольку он загрязняет глобальное пространство имен и может снизить читабельность.button1 = tk.Button(root, command=funA)
иbutton1 = ttk.Button(root, command=funA)
еслиtkinter
модуль расширения также импортируется? С*
синтаксисом обе строки кода будут выглядеть такbutton1 = Button(root, command=funA)
. Я бы не рекомендовал использовать этот синтаксис.Организация вашего приложения с использованием классов позволяет вам и другим, кто работает с вами, легко отлаживать проблемы и улучшать приложение.
Вы можете легко организовать свое приложение так:
источник
Вероятно, лучший способ научиться структурировать вашу программу - это читать код других людей, особенно если это большая программа, в которую многие люди внесли свой вклад. Посмотрев код многих проектов, вы должны понять, каким должен быть консенсусный стиль.
Python, как язык, особенный в том, что есть несколько строгих рекомендаций относительно того, как вы должны форматировать свой код. Первый - это так называемый «Zen of Python»:
На более практическом уровне есть PEP8 , руководство по стилю для Python.
Имея это в виду, я бы сказал, что ваш стиль кода не очень подходит, особенно для вложенных функций. Найдите способ сгладить их, используя классы или перемещая их в отдельные модули. Это сделает структуру вашей программы намного проще для понимания.
источник
Я лично не использую возражающий ориентированный подход, главным образом потому что это a) только мешает; б) вы никогда не будете использовать это как модуль.
но то, что здесь не обсуждается, это то, что вы должны использовать многопоточность или многопоточность. Всегда. в противном случае ваше приложение будет ужасным.
просто сделайте простой тест: запустите окно, а затем загрузите какой-нибудь URL или что-нибудь еще. изменения в том, что ваш пользовательский интерфейс не будет обновляться во время выполнения сетевого запроса. Это означает, что окно вашего приложения будет разбито. зависит от операционной системы, в которой вы находитесь, но в большинстве случаев она не будет перерисовываться, все, что вы перетаскиваете через окно, будет намазано на нем, пока процесс не вернется к основной петле TK.
источник