Python作为一门易学易用的语言,因其开放性、可扩展性等特点而备受欢迎。在Python的应用领域中,GUI编程也越来越被人们所关注。借助于Python的强大生态系统,我们能够很容易地从中选取合适的库来进行GUI编程,其中比较流行的库有Tkinter、PyQt、wxPython等等。本文将从Python GUI编程的背景和历史、GUI编程的基本框架、以及GUI设计中的常见场景等方面进行讲解,以帮助读者更好地入门Python GUI编程。
一、Tkinter
1、Tkinter的背景和历史
Tkinter是Python的标准GUI库之一,是一个用于创建GUI应用程序的工具包。Tkinter工具包是由Tcl/Tk GUI工具包改进而来的,Tcl/Tk是一种流行的跨平台脚本语言,在开源软件领域有着广泛的应用和影响。Tkinter提供了很多组件,如标签、按钮、滑块、菜单等等,同时也支持自定义组件,通过继承Tkinter的Frame类等方式,开发者可以创建自己的复杂组件。
2、Tkinter的基本框架
Tkinter的基本框架是一个主窗口(root), 可以把其他的组件如标签(Label)、按钮(Button)、文本框(Entry)等组合在一起。可以理解为Tkinter程序从根节点开始递归地生成出控件树。在Tkinter中每个控件都是一个对象,这个对象可以包含其他对象。每个控件都有自己的事件。Tkinter中所有的控件都有相应的方法,如绑定事件的方法、刷新组件的方法等。下面是一段Tkinter的代码:
import tkinter as tk
window = tk.Tk()
window.title("Hello Tkinter")
window.geometry("300x200")
lbl = tk.Label(window, text="This is a label", font=('Arial', 12))
lbl.pack()
btn = tk.Button(window, text="This is a button")
btn.pack()
window.mainloop()
在上面的示例中,我们创建了一个主窗口,并在窗口中添加了一个标签和一个按钮。代码中的window.mainloop()函数是主程序循环,它会一直等待有事件发生并响应用户的操作。
3、Tkinter的常见场景
在GUI编程中常见的场景与需求有很多,下面我们将结合Tkinter的常见示例和特性进行展开。 1)窗口布局和多窗口切换 使用Tkinter创建窗口之后,需要对窗口中的元素进行布局,可以使用pack、grid以及place等方法。同时,多个窗口之间的切换通常是非常频繁的,可以通过建立一个父窗口,然后通过按钮的点击事件来控制切换不同的子窗口来实现。 下面是一个简单的窗口切换和布局的示例代码:
import tkinter as tk
class Application(tk.Tk):
def __init__(self):
super().__init__()
self.title("My Application")
self.menu = tk.Menu(self)
self.menu.add_command(label="Window 1", command=self.show_frame_1)
self.menu.add_command(label="Window 2", command=self.show_frame_2)
self.option_add("*tearOff", False)
self.config(menu=self.menu)
self.frames = {}
for F in (Frame1, Frame2):
frame = F(self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame_1()
def show_frame_1(self):
self.frames[Frame1].tkraise()
def show_frame_2(self):
self.frames[Frame2].tkraise()
class Frame1(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.config(background='white')
tk.Label(self, text="This is Frame 1").pack()
class Frame2(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.config(background='grey')
tk.Label(self, text="This is Frame 2").pack()
app = Application()
app.mainloop()
在上面的示例中,我们创建了一个基本的多窗口布局并实现了窗口的切换。使用menu回调不同的show_frame_x方法,通过self.frames[F]来访问子窗口的实例并提升到前景实现窗口的切换。 2)组件交互 在GUI编程中,组件交互是一个比较常见的需求,例如当我们在一个文本框中输入内容时,希望下方的标签实时显示文本框中的内容。为了达到这样的效果,我们可以使用Tkinter的绑定机制,使用bind方法将组件的事件与特定的回调函数绑定,这样组件事件触发时便会自动调用相应的回调函数。 下面是一个简单的组件交互的示例代码:
import tkinter as tk
class Application(tk.Tk):
def __init__(self):
super().__init__()
self.title("Component Interaction")
self.var = tk.StringVar()
tk.Label(self, text="Enter something: ").pack(pady=10)
entry = tk.Entry(self, textvariable=self.var)
entry.pack(pady=10)
entry.bind('', self.show_var)
tk.Label(self, text="You entered: ").pack(pady=10)
self.lbl = tk.Label(self, text="")
self.lbl.pack()
def show_var(self, event):
self.lbl.config(text=self.var.get())
app = Application()
app.mainloop()
在上面的示例中,我们创建了一个简单的交互式组件,当用户在entry中输入内容时,响应的show_var方法会在label中实时显示出enter的内容。
二、PyQt
1、PyQt的背景和历史
PyQt是一个受欢迎的Python GUI编程工具库,是Python语言的跨平台GUI编程解决方案之一。PyQt是Python的绑定库,将Qt C++库绑定到Python的解释器上,使Python程序员可以使用C++的函数和类库。
2、PyQt的基本框架
PyQt的基本框架建立在Qt的基础上,其具有丰富的界面设计特性和GUI的快捷键等特色功能。在PyQt中,我们可以使用继承的方式来自定义组件,还可以通过PyQt的模型/视图框架,轻松地建立使用模型数据来驱动的数据视图,如列表、表格等等。 下面是一个简单的PyQt的代码示例:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 - Simple window'
self.left = 10
self.top = 10
self.width = 640
self.height = 480
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
label = QLabel(self)
label.setText("Hello World!")
label.move(50,50)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
在上面的示例中,我们创建了一个简单的窗口并在窗口中添加了一个标签。在PyQt中,我们使用QLabel来创建标签,并通过move方法将标签放置在窗口中的指定位置。
3、PyQt的常见场景
在PyQt中,灵活的界面设计和数据视图是其常见的一些功能,下面将着重介绍这些。 1)使用Qt Designer和UI文件来快速创建GUI界面 PyQt中,我们可以使用Qt Designer来创建和设计我们的GUI界面。Qt Designer是Qt的一个可视化工具,我们可以通过可视化界面轻松地快速设计出我们需要的GUI界面,拖拽组件实现布局,同时还可以使用Qt Designer的信号和槽工具来管理创建和管理组件的事件。 Qt Designer的另一个常见功能是支持导出UI文件和代码文件,我们可以直接将UI文件转换为Python代码文件或将其与Python代码进行集成。 下面是一个使用Qt Designer和UI文件快速创建GUI界面的示例代码:
from PyQt5 import QtWidgets, uic
import sys
class Ui(QtWidgets.QMainWindow):
def __init__(self):
super(Ui, self).__init__()
uic.loadUi('my_gui.ui', self)
self.show()
app = QtWidgets.QApplication(sys.argv)
window = Ui()
app.exec_()
在上面的示例中,“my_gui.ui”是我们使用Qt Designer创建的GUI界面文件,uic.loadUi('my_gui.ui', self) 用于将GUI布局加载到UI上并展示出来。 2)使用QDataWidgetMapper来创建数据视图 在基于数据的GUI应用中,我们需要使用模型和视图来在界面中呈现数据。PyQt中,我们可以使用Model / View架构来实现这个目的,主要是通过QAbstractItemModel、QTableView等API来实现。QDataWidgetMapper是Qt的一个组件,它可以将模型数据转换为视图,将更改转换为模型和视图数据。 下面是一个使用QDataWidgetMapper来创建数据视图的示例代码:
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import QApplication, QWidget, QDataWidgetMapper, \
QPushButton, QVBoxLayout, QHBoxLayout, QLineEdit, QTableView, QLabel
from PyQt5.QtCore import Qt
class MainWindow(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.resize(600, 400)
self.setWindowTitle('Data mapper example')
# Model
self.model = QStandardItemModel()
# Set Data
for row in range(5):
item1 = QStandardItem('Item %s' % row)
item2 = QStandardItem(str(row))
self.model.setItem(row, 0, item1)
self.model.setItem(row, 1, item2)
# View
self.view = QTableView()
self.view.setModel(self.model)
# Mapper
self.mapper = QDataWidgetMapper(self)
self.mapper.setModel(self.model)
self.mapper.addMapping(self.name_edit, 0)
self.mapper.addMapping(self.value_edit, 1)
# Buttons
button_previous = QPushButton(self)
button_previous.setText("Previous")
button_previous.clicked.connect(self.mapper.toPrevious)
button_next = QPushButton(self)
button_next.setText("Next")
button_next.clicked.connect(self.mapper.toNext)
# Edit views
self.name_edit = QLineEdit()
self.value_edit = QLineEdit()
# QVBoxLayout
vbox = QVBoxLayout()
vbox.addWidget(self.view)
hbox = QHBoxLayout()
hbox.addWidget(QLabel("Name"))
hbox.addWidget(self.name_edit)
hbox2 = QHBoxLayout()
hbox2.addWidget(QLabel("Value"))
hbox2.addWidget(self.value_edit)
vbox.addLayout(hbox)
vbox.addLayout(hbox2)
vbox.addWidget(button_previous)
vbox.addWidget(button_next)
# Set Layout
self.setLayout(vbox)
app = QApplication([])
gui = MainWindow()
gui.show()
app.exec_()
在上面的示例代码中,我们将模型数据中的数据项映射到相应的视图组件上,编辑视图组件子为模型数据提供了自然的入口,同时通过组合多个控件和QHBoxLayout / QVBoxLayout,实现了一个典型的数据视图功能。
三、wxPython
1、wxPython的背景和历史
wxPython是一个Python GUI应用程序开发框架,其中的wxWidgets提供了一个跨平台抽象层,为开发