本文参考文献为《Python GUI programming with tkinter》,作者Alan D. Moore
所有编程的入门都是hello world!
from tkinter import *
from tkinter.ttk import *
root = Tk()
label = Label(root, text = "hello world!")
label.pack()
root.mainloop()
ttk是一个比Tk相对好看的widgets,但还不知道好看在哪,而且注释掉没有发现什么变化。
root = Tk()用建立主窗体,是唯一的,也只能打开一个。
一般来说最后一行都是root.mainloop(),用来开户事件循环。其后面如果有语句,也是在主窗口退出后执行。
由于没有找到书中的源文件,自己把书中更好的hello world程序敲出来了。结果有问题。
import tkinter as tk
from tkinter import ttk
class HelloView(tk.Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.name = tk.StringVar()
self.hello_string = tk.StringVar()
self.hello_string.set("Hello world!")
name_label = ttk.Label(self, text = "Name:")
name_entry = ttk.Entry(self, textvariable = self.name)
ch_button = ttk.Button(self, text = "change", command = self.on_change)
hello_label = ttk.Label(self, textvariable = self.hello_string,
font = ("TkDefaultFont", 64), wraplength = 600)
name_label.grid(row = 0, column = 0, sticky = tk.W)
name_entry.grid(row = 0, column = 1, sticky = (tk.W + tk.E))
ch_button.grid(row = 0, column = 2, sticky = tk.E)
hello_label.grid(row = 1, column = 0, columnspan = 3)
self.columnconfigure(1, weight = 1)
def on_change(self):
if self.name.get().strip():
self.hello_string.set("Hello" + self.name.get())
else:
self.hello_string.set("hello world!")
class Myapplication(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.title("hello tkinter")
self.geometry("800x600")
self.resizable(width = False, height = False)
HelloView(self).grid(sticky = (tk.E+tk.W+tk.N+tk.S))
self.columnconfigure(0, weight = 1)
if __name__ == '__main__':
app = Myapplication()
app.mainloop()
运行时问题提示为
先不管吧。定位不到问题。跟着书上的节奏来,好读书不求甚解,看什么时候出现会意。
1。首先是导入的不在是*,而是tk和ttk。这样可以防止全局命名空间不出现混乱,而且可以消除潜在的bugs。
2。接着定义一个Tkinter.Frame的子类HelloView。Frame类是Tk widget的通用类,可以用做一个容器来放置更多的widgets,这样就可以把无论多少个widgets都可以当做一个widget来对待。super()函数提供了顶层类(super class,不知道该如何翻译)的引用,本例中是tk.Frame。*args和**kwargs定义了Frame的所有参数。
3。创建两个变量用来存储命名和字符。Tk变量包含StringVar, IntVar,DoubleVar,BooleanVar。然后创建一个Label和Entry。
4。定义一个按钮。这里的按钮调用了一个函数,on_change,出问题也是在这里出的问题。未找到该属性。
5。再创建一个显示文本的Label。
6。对所有Widgets进行布局。
7。定义按钮的回调函数on_change。
8。定义一个真实的应用,这个里面调用tk的子类,表征主应用目标。
9。因为tk是根窗口,所以在super初始化函数中不需要parent。
10。将自定义子类HelloView加入到主窗口。
11。增加执行代码。
本例中是不能直接运行的,只有在不调用on_change时才可以运行。
ch_button = ttk.Button(self, text = "change") #, command = self.on_change)
运行结果如下图所示。
今天终于找到原因了:
定义on_change时,多缩进了,所以找不到该函数