chris aung
La siguiente es la estructura general de mi programa típico de 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
y funC
traerá otro Toplevel
ventana con widgets cuando el usuario hace clic en el botón 1, 2, 3.
Me pregunto si esta es la forma correcta de escribir un programa Python Tkinter. Claro, funcionará incluso si escribo de esta manera, pero ¿es la mejor manera? Suena estúpido, pero cuando veo el código que escribieron otras personas, su código no está desordenado con un montón de funciones y, en su mayoría, tienen clases.
¿Hay alguna estructura específica que debamos seguir como buena práctica? ¿Cómo debo planificar antes de comenzar a escribir un programa en Python?
Sé que no existen las mejores prácticas en programación y tampoco las estoy pidiendo. Solo quiero algunos consejos y explicaciones para mantenerme en la dirección correcta mientras aprendo Python por mi cuenta.
Bryan Oakley
Abogo por un enfoque orientado a objetos. Esta es la plantilla con la que empiezo:
# Use Tkinter for python 2, tkinter for python 3
import tkinter as tk
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
<create the rest of your GUI here>
if __name__ == "__main__":
root = tk.Tk()
MainApplication(root).pack(side="top", fill="both", expand=True)
root.mainloop()
Las cosas importantes a notar son:
-
No uso una importación de comodines. Importo el paquete como “tk”, lo que requiere que prefijo todos los comandos con
tk.
. Esto evita la contaminación del espacio de nombres global, además de que hace que el código sea completamente obvio cuando usa clases Tkinter, clases ttk o algunas propias. -
La aplicación principal es una clase.. Esto le brinda un espacio de nombres privado para todas sus devoluciones de llamada y funciones privadas y, en general, facilita la organización de su código. En un estilo de procedimiento, debe codificar de arriba hacia abajo, definiendo funciones antes de usarlas, etc. Con este método, no lo hace, ya que en realidad no crea la ventana principal hasta el último paso. Prefiero heredar de
tk.Frame
solo porque normalmente empiezo creando un marco, pero de ninguna manera es necesario.
Si su aplicación tiene ventanas de nivel superior adicionales, recomiendo que cada una de ellas sea una clase separada, heredando de tk.Toplevel
. Esto le brinda todas las mismas ventajas mencionadas anteriormente: las ventanas son atómicas, tienen su propio espacio de nombres y el código está bien organizado. Además, facilita colocar cada uno en su propio módulo una vez que el código comienza a crecer.
Finalmente, es posible que desee considerar el uso de clases para cada parte importante de su interfaz. Por ejemplo, si está creando una aplicación con una barra de herramientas, un panel de navegación, una barra de estado y un área principal, podría crear cada una de esas clases. Esto hace que su código principal sea bastante pequeño y fácil de entender:
class Navbar(tk.Frame): ...
class Toolbar(tk.Frame): ...
class Statusbar(tk.Frame): ...
class Main(tk.Frame): ...
class MainApplication(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.statusbar = Statusbar(self, ...)
self.toolbar = Toolbar(self, ...)
self.navbar = Navbar(self, ...)
self.main = Main(self, ...)
self.statusbar.pack(side="bottom", fill="x")
self.toolbar.pack(side="top", fill="x")
self.navbar.pack(side="left", fill="y")
self.main.pack(side="right", fill="both", expand=True)
Dado que todas esas instancias comparten un padre común, el padre se convierte efectivamente en la parte del “controlador” de una arquitectura modelo-vista-controlador. Entonces, por ejemplo, la ventana principal podría colocar algo en la barra de estado llamando self.parent.statusbar.set("Hello, world")
. Esto le permite definir una interfaz simple entre los componentes, lo que ayuda a mantener el acoplamiento al mínimo.
-
Secundo el enfoque orientado a objetos. Sin embargo, abstenerse de usar la herencia en su clase que llama a la GUI es una buena idea, según mi experiencia. Le ofrece más flexibilidad si los objetos Tk y Frame son atributos de una clase que no hereda de nada. De esta forma, puede acceder a los objetos Tk y Frame más fácilmente (y de forma menos ambigua), y destruir uno no destruirá todo en su clase si no lo desea. Olvidé la razón exacta por la que esto es vital en algunos programas, pero te permite hacer más cosas.
– Brotsyorfuzthrāx
19 mayo 2014 a las 21:38
-
El enfoque OOP aquí es agradable y elegante (y trivial), pero ¿qué pasa con la asignación de responsabilidades? ¿Qué clase debería ser responsable de crear cada widget? ¿Qué clase debería ser responsable de diseñarlos de la manera correcta? ¿Cómo administrar los acoplamientos controlador-GUI de una manera que no rompa los límites entre ellos?
– Blazej Michalik
5 de enero de 2017 a las 11:56
-
Para aplicaciones complejas de ventanas múltiples, ¿recomienda separar cada clase de ventana en su propio archivo? (es decir:
main_window.py
,login_window.py
,import_file_window.py
)– Stevoisiak
20 de febrero de 2018 a las 20:54
-
@MartijnPieters: sí, mi opinión cambió, lo expliqué en la otra respuesta.
–Bryan Oakley
22 de agosto de 2022 a las 14:57
-
@BryanOakley: palma de la cara ¡Así lo haces, lo siento!
– Martijn Pieters
♦22 de agosto de 2022 a las 20:24
alejandro
Poner cada una de sus ventanas de nivel superior en su propia clase separada le brinda la reutilización del código y una mejor organización del código. Cualquier botón y método relevante que esté presente en la ventana debe definirse dentro de esta clase. Aquí hay un ejemplo (tomado de aquí):
import tkinter as tk
class Demo1:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.button1 = tk.Button(self.frame, text="New Window", width = 25, command = self.new_window)
self.button1.pack()
self.frame.pack()
def new_window(self):
self.newWindow = tk.Toplevel(self.master)
self.app = Demo2(self.newWindow)
class Demo2:
def __init__(self, master):
self.master = master
self.frame = tk.Frame(self.master)
self.quitButton = tk.Button(self.frame, text="Quit", width = 25, command = self.close_windows)
self.quitButton.pack()
self.frame.pack()
def close_windows(self):
self.master.destroy()
def main():
root = tk.Tk()
app = Demo1(root)
root.mainloop()
if __name__ == '__main__':
main()
Ver también:
- hola mundo simple de tkinter docs
- Código de ejemplo de Tkinter para varias ventanas, ¿por qué los botones no se cargan correctamente?
- Tkinter: Cómo mostrar/ocultar una ventana
Espero que ayude.
-
¿Por qué debería usar
root
como argumento para laDemo1
objeto, y por qué no? Como se ve en muchas de las respuestas en el hilo actual y en Internet.– carloswm85
14 de julio de 2021 a las 23:52
-
@ carloswm85 En mi opinión, depende de si la clase que crea es un marco (entonces debe colocarse en el padre (raíz) y, por lo tanto, la raíz debe pasarse como argumento); o si la clase hereda tk en sí misma y, por lo tanto, no necesita pasar ningún argumento, ya que su clase será la propia instancia de tk.
– mamg2909
30 ene a las 20:43
De serie
Esta no es una mala estructura; funcionará bien. Sin embargo, debe tener funciones en una función para ejecutar comandos cuando alguien hace clic en un botón o algo así.
Entonces, lo que podría hacer es escribir clases para estos y luego tener métodos en la clase que manejen comandos para los clics de botón y demás.
Aquí hay un ejemplo:
import tkinter as tk
class Window1:
def __init__(self, master):
pass
# Create labels, entries,buttons
def button_click(self):
pass
# If button is clicked, run this method and open window 2
class Window2:
def __init__(self, master):
#create buttons,entries,etc
def button_method(self):
#run this when button click to close window
self.master.destroy()
def main(): #run mianloop
root = tk.Tk()
app = Window1(root)
root.mainloop()
if __name__ == '__main__':
main()
Por lo general, los programas tk con múltiples ventanas son múltiples clases grandes y en el __init__
se crean todas las entradas, etiquetas, etc. y luego cada método es para manejar eventos de clic de botón
Realmente no hay una manera correcta de hacerlo, lo que sea que funcione para usted y haga el trabajo siempre que sea legible y pueda explicarlo fácilmente porque si no puede explicar fácilmente su programa, probablemente haya una mejor manera de hacerlo. .
Echa un vistazo a Pensando en Tkinter.
-
“Pensando en Tkinter” aboga por las importaciones globales, lo que me parece un muy mal consejo.
–Bryan Oakley
4 de julio de 2013 a las 13:20
-
Eso es cierto, no sugiero que uses globales, solo algunos de los métodos de estructura de la clase principal, tienes razón 🙂
– Serie
4 de julio de 2013 a las 13:22
OOP debe ser el enfoque y frame
debería ser un variable de clase en lugar de Instancia variable.
from Tkinter import *
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame,
text="QUIT", fg="red",
command=frame.quit)
self.button.pack(side=LEFT)
self.slogan = Button(frame,
text="Hello",
command=self.write_slogan)
self.slogan.pack(side=LEFT)
def write_slogan(self):
print "Tkinter is easy to use!"
root = Tk()
app = App(root)
root.mainloop()
Referencia: http://www.python-course.eu/tkinter_buttons.php
Mi forma preferida de hacerlo es como la respuesta de Bryan Oakley. Aquí hay un ejemplo, hecho por Sentdex en Youtube, ve a ver su lista de reproducción “GUI con Tkinter”.
Creo que es realmente relevante ponerlo aquí porque es un gran ejemplo para el OP, por lo que también responde a esta respuesta que fue mejorada por 35 personas y no fue respondida;
@Bryan Oakley, ¿conoce algún buen código de muestra en Internet que pueda estudiar su estructura? — Chris Aung 05 jul.
import tkinter as tk LARGE_FONT= ("Verdana", 12) class SeaofBTCapp(tk.Tk): """ tkinter example app with OOP """ def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) container = tk.Frame(self) container.pack(side="top", fill="both", expand = True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for frame_class in (StartPage,PageOne, PageTwo): frame = frame_class(container, self) self.frames[frame_class] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(StartPage) def show_frame(self, cont): """ Put specific frame on top """ frame = self.frames
Chris AungThe following is the overall structure of my typical Python Tkinter program.
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
andfunC
will bring up anotherToplevel
window with widgets when user click on button 1, 2, 3.I am wondering if this is the right way to write a Python Tkinter program? Sure, it will work even if I write this way, but is it the best way? It sounds stupid but when I see the code other people written, their code is not messed up with bunch of functions and mostly they have classes.
Is there any specific structure that we should follow as good practice? How should I plan before start writing a Python program?
I know there is no such thing as best practice in programming and I am not asking for it either. I just want some advice and explanations to keep me on the right direction as I am learning Python by myself.
Here is an excellent tutorial on tkinter GUI design, with a couple examples -- python-textbok.readthedocs.org/en/latest/… Here is another example with an MVC design pattern -- sukhbinder.wordpress.com/2014/12/25/…
– BondolinMay 18, 2015 at 18:39
I advocate an object oriented approach. This is the template that I start out with:
# Use Tkinter for python 2, tkinter for python 3 import tkinter as tk class MainApplication(tk.Frame): def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) self.parent = parent <create the rest of your GUI here> if __name__ == "__main__": root = tk.Tk() MainApplication(root).pack(side="top", fill="both", expand=True) root.mainloop()
The important things to notice are:
I don't use a wildcard import. I import the package as "tk", which requires that I prefix all commands with
tk.
. This prevents global namespace pollution, plus it makes the code completely obvious when you are using Tkinter classes, ttk classes, or some of your own.The main application is a class. This gives you a private namespace for all of your callbacks and private functions, and just generally makes it easier to organize your code. In a procedural style you have to code top-down, defining functions before using them, etc. With this method you don't since you don't actually create the main window until the very last step. I prefer inheriting from
tk.Frame
just because I typically start by creating a frame, but it is by no means necessary.If your app has additional toplevel windows, I recommend making each of those a separate class, inheriting from
tk.Toplevel
. This gives you all of the same advantages mentioned above -- the windows are atomic, they have their own namespace, and the code is well organized. Plus, it makes it easy to put each into its own module once the code starts to get large.Finally, you might want to consider using classes for every major portion of your interface. For example, if you're creating an app with a toolbar, a navigation pane, a statusbar, and a main area, you could make each one of those classes. This makes your main code quite small and easy to understand:
class Navbar(tk.Frame): ... class Toolbar(tk.Frame): ... class Statusbar(tk.Frame): ... class Main(tk.Frame): ... class MainApplication(tk.Frame): def __init__(self, parent, *args, **kwargs): tk.Frame.__init__(self, parent, *args, **kwargs) self.statusbar = Statusbar(self, ...) self.toolbar = Toolbar(self, ...) self.navbar = Navbar(self, ...) self.main = Main(self, ...) self.statusbar.pack(side="bottom", fill="x") self.toolbar.pack(side="top", fill="x") self.navbar.pack(side="left", fill="y") self.main.pack(side="right", fill="both", expand=True)
Since all of those instances share a common parent, the parent effectively becomes the "controller" part of a model-view-controller architecture. So, for example, the main window could place something on the statusbar by calling
self.parent.statusbar.set("Hello, world")
. This allows you to define a simple interface between the components, helping to keep coupling to a minimun.
I second the object-oriented approach. However, refraining from using inheritance on your class that calls the GUI is a good idea, in my experience. It offers you more flexibility if both the Tk and Frame objects are attributes of a class which doesn't inherit from anything. This way you can access the Tk and Frame objects more easily (and less ambiguously), and destroying one won't destroy everything in your class if you don't want it to. I forgot the exact reason why this is vital in some programs, but it does allow you to do more things.
May 19, 2014 at 21:38
OOP approach here is nice and dandy (and trivial), but what about assigning responsibilities? Which class should be responsible for creating each widget? Which class should be responsible for layouting them in the right way? How to manage controller-gui couplings in a way that doesn't break the boundaries inbetween them?
Jan 5, 2017 at 11:56
For complex multi-window applications, do you recommend separating each window-class into it's own file? (ie:
main_window.py
,login_window.py
,import_file_window.py
)Feb 20, 2018 at 20:54
@MartijnPieters: yes, my view changed, I explained that in the other answer.
Aug 22, 2022 at 14:57
Putting each of your top-level windows into it's own separate class gives you code re-use and better code organization. Any buttons and relevant methods that are present in the window should be defined inside this class. Here's an example (taken from here):
import tkinter as tk class Demo1: def __init__(self, master): self.master = master self.frame = tk.Frame(self.master) self.button1 = tk.Button(self.frame, text="New Window", width = 25, command = self.new_window) self.button1.pack() self.frame.pack() def new_window(self): self.newWindow = tk.Toplevel(self.master) self.app = Demo2(self.newWindow) class Demo2: def __init__(self, master): self.master = master self.frame = tk.Frame(self.master) self.quitButton = tk.Button(self.frame, text="Quit", width = 25, command = self.close_windows) self.quitButton.pack() self.frame.pack() def close_windows(self): self.master.destroy() def main(): root = tk.Tk() app = Demo1(root) root.mainloop() if __name__ == '__main__': main()
Also see:
- simple hello world from tkinter docs
- Tkinter example code for multiple windows, why won't buttons load correctly?
- Tkinter: How to Show / Hide a Window
Hope that helps.
Why should I use
root
as an argument for theDemo1
object, and why not? As seen in many of the answers in the current thread and around the internet.Jul 14, 2021 at 23:52
@carloswm85 IMO, it depends on whether the class you create is a frame (then it needs to be placed in the parent (root), and thus root needs to be passed as an argument); or whether the class inherits tk itself, and hence you don't need to pass any argument, as your class will be the tk instace itself.
– mamg2909Jan 30 at 20:43
This isn't a bad structure; it will work just fine. However, you do have to have functions in a function to do commands when someone clicks on a button or something
So what you could do is write classes for these then have methods in the class that handle commands for the button clicks and such.
Here's an example:
import tkinter as tk class Window1: def __init__(self, master): pass # Create labels, entries,buttons def button_click(self): pass # If button is clicked, run this method and open window 2 class Window2: def __init__(self, master): #create buttons,entries,etc def button_method(self): #run this when button click to close window self.master.destroy() def main(): #run mianloop root = tk.Tk() app = Window1(root) root.mainloop() if __name__ == '__main__': main()
Usually tk programs with multiple windows are multiple big classes and in the
__init__
all the entries, labels etc are created and then each method is to handle button click eventsThere isn't really a right way to do it, whatever works for you and gets the job done as long as its readable and you can easily explain it because if you cant easily explain your program, there probably is a better way to do it.
Take a look at Thinking in Tkinter.
"Thinking in Tkinter" advocates global imports, which I think is very bad advice.
Jul 4, 2013 at 13:20
Thts true i dont suggest you use globals just some of the main class methos structure youre right 🙂
– SerialJul 4, 2013 at 13:22
OOP should be the approach and
frame
should be a class variable instead of instance variable.from Tkinter import * class App: def __init__(self, master): frame = Frame(master) frame.pack() self.button = Button(frame, text="QUIT", fg="red", command=frame.quit) self.button.pack(side=LEFT) self.slogan = Button(frame, text="Hello", command=self.write_slogan) self.slogan.pack(side=LEFT) def write_slogan(self): print "Tkinter is easy to use!" root = Tk() app = App(root) root.mainloop()
My preferred way of doing it is like Bryan Oakley's answer.
Here's an example, made by Sentdex on Youtube, go check his "GUIs with Tkinter" playlist.I think it's really relevant to put it here because it's a great example for the OP, and so it also answers this answer that was upped by 35 people and wasn't answered;
@Bryan Oakley do you know any good sample codes on internet that i can
study their structure? – Chris Aung Jul 5 '13 at 8:35import tkinter as tk LARGE_FONT= ("Verdana", 12) class SeaofBTCapp(tk.Tk): """ tkinter example app with OOP """ def __init__(self, *args, **kwargs): tk.Tk.__init__(self, *args, **kwargs) container = tk.Frame(self) container.pack(side="top", fill="both", expand = True) container.grid_rowconfigure(0, weight=1) container.grid_columnconfigure(0, weight=1) self.frames = {} for frame_class in (StartPage,PageOne, PageTwo): frame = frame_class(container, self) self.frames[frame_class] = frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(StartPage) def show_frame(self, cont): """ Put specific frame on top """ frame = self.frames[cont] frame.tkraise() class StartPage(tk.Frame): """ Starting frame for app """ def __init__(self, parent, controller): tk.Frame.__init__(self,parent,bg='grey') label = tk.Label(self, text="Start Page", font=LARGE_FONT) label.pack(pady=10,padx=10) button_page1 = tk.Button(self, text="Visit Page 1", command= lambda: controller.show_frame(PageOne)) button_page1.pack() button_page2 = tk.Button(self, text="Visit Page 2", command= lambda: controller.show_frame(PageTwo)) button_page2.pack() class PageOne(tk.Frame): """ First page of program """ def __init__(self,parent,controller): tk.Frame.__init__(self,parent,bg='light blue') label = tk.Label(self, text="Page one", font=LARGE_FONT) label.pack(pady=10,padx=10) button_home = tk.Button(self, text="Back to Home", command= lambda: controller.show_frame(StartPage)) button_home.pack() button_home = tk.Button(self, text="Go to page2", command= lambda: controller.show_frame(PageTwo)) button_home.pack() class PageTwo(tk.Frame): """ First page of program """ def __init__(self,parent,controller): tk.Frame.__init__(self,parent,bg='light green') label = tk.Label(self, text="Page two", font=LARGE_FONT) label.pack(pady=10,padx=10) button_home = tk.Button(self, text="Back to Home", command= lambda: controller.show_frame(StartPage)) button_home.pack() button_home = tk.Button(self, text="Go to page1", command= lambda: controller.show_frame(PageOne)) button_home.pack() app = SeaofBTCapp() app.mainloop()
Find the code here also : [https://pythonprogramming.net/change-show-new-frame-tkinter/]
That tutorial most likely used Bryan's other answer right here. These posts came far before that tutorial you reference.
– RorySep 1, 2022 at 23:14
@Rory obviously, that is why I cited Bryan Oakley in my first sentence "My preferred way of doing it is like Bryan Oakley's answer. Here's an example, made by Sentdex on Youtube, go check his "GUIs with Tkinter" playlist".. I don't see your point here..
– Gab ПКOct 27, 2022 at 19:28
Organizing your application using class make it easy to you and others who work with you to debug problems and improve the app easily.
You can easily organize your application like this:
class hello(Tk): def __init__(self): super(hello, self).__init__() self.btn = Button(text = "Click me", command=close) self.btn.pack() def close(): self.destroy() app = hello() app.mainloop()
That tutorial most likely used Bryan's other answer right here. These posts came far before that tutorial you reference.
– RorySep 1, 2022 at 23:14
@Rory obviously, that is why I cited Bryan Oakley in my first sentence "My preferred way of doing it is like Bryan Oakley's answer. Here's an example, made by Sentdex on Youtube, go check his "GUIs with Tkinter" playlist".. I don't see your point here..
– Gab ПКOct 27, 2022 at 19:28
Probably the best way to learn how to structure your program is by reading other people's code, especially if it's a large program to which many people have contributed. After looking at the code of many projects, you should get an idea of what the consensus style should be.
Python, as a language, is special in that there are some strong guidelines as to how you should format your code. The first is the so-called "Zen of Python":
- Beautiful is better than ugly.
- Explicit is better than implicit.
- Simple is better than complex.
- Complex is better than complicated.
- Flat is better than nested.
- Sparse is better than dense.
- Readability counts.
- Special cases aren't special enough to break the rules.
- Although practicality beats purity.
- Errors should never pass silently.
- Unless explicitly silenced.
- In the face of ambiguity, refuse the temptation to guess.
- There should be one-- and preferably only one --obvious way to do it.
- Although that way may not be obvious at first unless you're Dutch.
- Now is better than never.
- Although never is often better than right now.
- If the implementation is hard to explain, it's a bad idea.
- If the implementation is easy to explain, it may be a good idea.
- Namespaces are one honking great idea -- let's do more of those!
On a more practical level, there is PEP8, the style guide for Python.
With those in mind, I would say that your code style doesn't really fit, particularly the nested functions. Find a way to flatten those out, either by using classes or moving them into separate modules. This will make the structure of your program much easier to understand.
-1 for using the Zen of Python. While it's all good advice, it doesn't directly address the question that was asked. Take the last paragraph out and this answer could apply to almost every python question on this site. It's good, positive advice, but it doesn't answer the question.
Jul 13, 2013 at 21:31
@BryanOakley I disagree with you on that. Yes, the Zen of Python is broad and can be used to address many questions. He did mention in the final paragraph to opt for classes or placing the functions in separate modules. He also mentioned PEP8, a style guide for Python, with references to it. Although not a direct answer, I think this answer is credible in the fact that it mentions many different routes that can be taken. That's just my opinion
– AliceJan 13, 2017 at 10:39
I came here looking for answers to this specific question. Even for an open-ended question, I can't do anything with this response. -1'd from me as well.
– jonathanMar 16, 2018 at 21:32
No way, the question is about to structure a tkinter app, nothing about styling/coding/zen guidelines. Easy as quoting @Arbiter "Although not a direct answer", so, it's NOT an answer. This is like "maybe yes and maybe no", with zen prepended.
– m3ndaAug 12, 2018 at 1:02
frame.tkraise()
class StartPage(tk.Frame):
"""
Starting frame for app
"""def __init__(self, parent, controller):
tk.Frame.__init__(self,parent,bg='grey')
label = tk.Label(self, text="Start Page", font=LARGE_FONT)
label.pack(pady=10,padx=10)button_page1 = tk.Button(self, text="Visit Page 1", command= lambda: controller.show_frame(PageOne))
button_page1.pack()button_page2 = tk.Button(self, text="Visit Page 2", command= lambda: controller.show_frame(PageTwo))
button_page2.pack()class PageOne(tk.Frame):
"""
First page of program
"""def __init__(self,parent,controller):
tk.Frame.__init__(self,parent,bg='light blue')
label = tk.Label(self, text="Page one", font=LARGE_FONT)
label.pack(pady=10,padx=10)button_home = tk.Button(self, text="Back to Home", command= lambda: controller.show_frame(StartPage))
button_home.pack()button_home = tk.Button(self, text="Go to page2", command= lambda: controller.show_frame(PageTwo))
button_home.pack()class PageTwo(tk.Frame):
"""
First page of program
"""def __init__(self,parent,controller):
tk.Frame.__init__(self,parent,bg='light green')
label = tk.Label(self, text="Page two", font=LARGE_FONT)
label.pack(pady=10,padx=10)button_home = tk.Button(self, text="Back to Home", command= lambda: controller.show_frame(StartPage))
button_home.pack()button_home = tk.Button(self, text="Go to page1", command= lambda: controller.show_frame(PageOne))
button_home.pack()app = SeaofBTCapp()
app.mainloop()
Encuentra el código aquí también: [https://pythonprogramming.net/change-show-new-frame-tkinter/]
-
Ese tutorial probablemente usó la otra respuesta de Bryan aquí. Estas publicaciones llegaron mucho antes de ese tutorial al que hace referencia.
–Rory
1 de septiembre de 2022 a las 23:14
-
@Rory obviamente, es por eso que cité a Bryan Oakley en mi primera oración “Mi forma preferida de hacerlo es como la respuesta de Bryan Oakley. Aquí hay un ejemplo, hecho por Sentdex en Youtube, ve a ver su lista de reproducción” GUI con Tkinter “”. No veo tu punto aquí..
– Gab ПК
27 oct 2022 a las 19:28
muyustan
La organización de su aplicación mediante la clase facilita que usted y otras personas que trabajan con usted depuren problemas y mejoren la aplicación fácilmente.
Puede organizar fácilmente su aplicación de esta manera:
class hello(Tk):
def __init__(self):
super(hello, self).__init__()
self.btn = Button(text = "Click me", command=close)
self.btn.pack()
def close():
self.destroy()
app = hello()
app.mainloop()
-
Ese tutorial probablemente usó la otra respuesta de Bryan aquí. Estas publicaciones llegaron mucho antes de ese tutorial al que hace referencia.
–Rory
1 de septiembre de 2022 a las 23:14
-
@Rory obviamente, es por eso que cité a Bryan Oakley en mi primera oración “Mi forma preferida de hacerlo es como la respuesta de Bryan Oakley. Aquí hay un ejemplo, hecho por Sentdex en Youtube, ve a ver su lista de reproducción” GUI con Tkinter “”. No veo tu punto aquí..
– Gab ПК
27 oct 2022 a las 19:28
Rosa Inbar
Probablemente la mejor manera de aprender a estructurar su programa es leyendo el código de otras personas, especialmente si se trata de un programa grande en el que han contribuido muchas personas. Después de mirar el código de muchos proyectos, debería tener una idea de cuál debería ser el estilo de consenso.
Python, como lenguaje, es especial porque hay algunas pautas sólidas sobre cómo debe formatear su código. El primero es el llamado “Zen de Python”:
- Hermoso es mejor que feo.
- Explícito es mejor que implícito.
- Lo simple es mejor que lo complejo.
- Complejo es mejor que complicado.
- Plano es mejor que anidado.
- Disperso es mejor que denso.
- La legibilidad cuenta.
- Los casos especiales no son lo suficientemente especiales como para romper las reglas.
- Aunque la practicidad le gana a la pureza.
- Los errores nunca deben pasar en silencio.
- A menos que se silencie explícitamente.
- Frente a la ambigüedad, rechace la tentación de adivinar.
- Debe haber una, y preferiblemente solo una, forma obvia de hacerlo.
- Aunque esa manera puede no ser obvia al principio a menos que seas holandés.
- Ahora es mejor que nunca.
- Aunque nunca es a menudo mejor que bien ahora.
- Si la implementación es difícil de explicar, es una mala idea.
- Si la implementación es fácil de explicar, puede ser una buena idea.
- Los espacios de nombres son una gran idea, ¡hagamos más de eso!
En un nivel más práctico, hay PEP8la guía de estilo de Python.
Con eso en mente, diría que el estilo de su código realmente no encaja, particularmente las funciones anidadas. Encuentre una manera de aplanarlos, ya sea usando clases o moviéndolos a módulos separados. Esto hará que la estructura de su programa sea mucho más fácil de entender.
-
-1 por usar el Zen de Python. Si bien todos son buenos consejos, no abordan directamente la pregunta que se hizo. Quite el último párrafo y esta respuesta podría aplicarse a casi todas las preguntas de Python en este sitio. Es un consejo bueno y positivo, pero no responde la pregunta.
–Bryan Oakley
13 de julio de 2013 a las 21:31
-
@BryanOakley No estoy de acuerdo contigo en eso. Sí, el Zen de Python es amplio y se puede utilizar para abordar muchas preguntas. Mencionó en el párrafo final optar por clases o ubicar las funciones en módulos separados. También mencionó PEP8, una guía de estilo para Python, con referencias a ella. Aunque no es una respuesta directa, creo que esta respuesta es creíble en el hecho de que menciona muchas rutas diferentes que se pueden tomar. esa es solo mi opinion
– Alicia
13 de enero de 2017 a las 10:39
-
Vine aquí buscando respuestas a esta pregunta específica. Incluso para una pregunta abierta, no puedo hacer nada con esta respuesta. -1 de mí también.
– jonathan
16/03/2018 a las 21:32
-
De ninguna manera, la pregunta se trata de estructurar un tkinter aplicación, nada sobre estilo/codificación/directrices zen. Tan fácil como citar a @Arbiter “Aunque no es una respuesta directa”, entonces NO es una respuesta. Esto es como “quizás sí y quizás no”, con zen antepuesto.
– m3nda
12 de agosto de 2018 a las 1:02
Aquí hay un excelente tutorial sobre el diseño de GUI de tkinter, con un par de ejemplos: python-textbok.readthedocs.org/en/latest/… Aquí hay otro ejemplo con un patrón de diseño MVC: sukhbinder.wordpress.com/2014/12/25/…
– Bondolina
18 mayo 2015 a las 18:39