使用 PyQt 工具包开发 PyQt 程序总结
python 支持多种图形界面的第三方库。包括:
- TK 图形库,由 Tcl 语言开发的。python 调用内置 tkinter 库。
- wxWidgets 图形库,由 C++语言开发。Python 第三方库 wxPython 封装了此图形库。
- Qt 非常强大的应用程序开发框架,可开发 GUI 或非 GUI 程序。python 第三方库 PyQt。
- GTK 对应 python 的第三库为 PyGTK。
Qt 概念
Qt 是一个由 C++编写的跨平台的应用程序开发框架。可以用来开发 GUI 程序,也可以用来开发非 GUI 程序。目前 Qt 有两种版本,一种是商业版本(付费使用),另一种则是基于(L)GPL v3 的开源版本。
Qt 具体在某些方面的应用,大家可以访问 Qt 官网) 进行查看。
PyQt 概念
Qt 和 PyQt 有什么区别?简而言之,PyQt 是 Qt 的一个 wrapper(封装)。PyQt 为 python 开发 GUI 程序提供了解决方案,同样 PyQt 也是跨平台的,支持 Linux、Windows、Mac OS。从 PyQt4 开始,所有平台上均支持 GPL(General Public License) 协议即开源协议。
PyQt 官方网站请 点击 。PyQt4 官方文档请 点击 。
版本
目前有 PyQt4 和 PyQt5 两种版本,且两者不兼容。PyQt4 在官网介绍说明中,未来将不会得到支持,所以 PyQt5 是未来的一个趋势。当然目前 PyQt4 使用最为广泛。
本文主要以 PyQt4 进行介绍。
安装
PyQt 安装这一块,可能比较复杂。需要下载包手动安装。工具包 下载地址 。
首先 PyQt 工具包版本需要与 Python 版本进行匹配。版本位数也必须要匹配,比如 python 解释器是 32 位,那么工具包也必须是 32 位的。这里推荐大家版本都采用 64 位。
组件模块
PyQt4 为跨平台的工具包,它包括了 300 多个类和 6000 多个方法。由于过多的类和方法,整个工具库被划分成了多个模块。不同模块主要实现不同的功能,这一部分大家主要了解以下模块的主要作用。并学习掌握几个关键模块。
具体模块如下:
- QtGui 模块包括图形化窗口组件和及相关类。包括如按钮、窗体、状态栏、滑块、位图、颜色、字体等等。
- QtCore 模块包括了核心的非 GUI 功能,该模块用来对时间、文件、目录、各种数据类型、流、网址、媒体类型、线程或进程进行处理。
- QtHelp 模块包含了用于创建和查看可查找的文档的类。
- QtNetwork 模块包括网络编程的类。这些类可以用来编写 TCP/IP 和 UDP 的客户端和服务器。它们使得网络编程更容易和便捷。
- QtOpenGL 模块使用 OpenGL 库来渲染 3D 和 2D 图形。该模块使得 Qt GUI 库和 OpenGL 库无缝集成。
- QtScript 模块包含了使 PyQt 应用程序使用 JavaScript 解释器编写脚本的类。
- QtSql 模块提供操作数据库的类。
- QtSvg 模块提供了显示 SVG 文件内容的类。可缩放矢量图形(SVG) 是一种用 XML 描述二维图形和图形应用的语言。
- QtTest 模块包含了对 PyQt 应用程序进行单元测试的功能。(PyQt 没有实现完全的 Qt 单元测试框架,相反,它假设使用标准的 Python 单元测试框架来实现模拟用户和 GUI 进行交互。)
- QtWebKit 模块实现了基于开源浏览器引擎 WebKit 的浏览器引擎。
- QtXml 包括处理 XML 文件的类,该模块提供了 SAX 和 DOM API 的接口。
- QtAssistant 模块包含的类允许集成 Qt Assistant 到 PyQt 应用程序中,提供在线帮助。
- QtDesigner 模块包含的类允许使用 PyQt 扩展 Qt Designer。
- uic 模块包含的类用来处理.ui 文件,该文件由 Qt Designer 创建,用于描述整个或者部分用户界面。它包含的加载.ui 文件和直接渲染以及从.ui 文件生成 Python 代码为以后执行的类。
常用组件
以下描述组件均为 GUI 界面的组件,属于 QtGui 模块。重点关注几个常用组件的信号和方法。
1、按键 QPushButton
# 初始化 button 类,得到一个按键对象 ok_button = QtGui.QPushButton('OK', widget)
信号:
- clicked():按键被点击后触发的信号;
- pressed():按键倍按下触发的信号;
- released():按键被释放(抬起)时触发的信号;
构造方法:
# 添加一个按键,并设置图标和文本 __init__(self, QIcon, QString_text, QWidget parent = None)
2、行编辑框 QLineEdit
# 初始化类,得到对象 useredit = QtGui.QLineEdit(widget)
信号:
- cursorPositionChanged(int,int):光标位置改变触发;
- editingFinished():编辑完成后触发的信号(编辑框失去光标);
- textChanged(const QString&):文本内容改变时触发的信号;
构造方法:
# 生成一个行编辑框 __init__(self, QWidget parent = None) # 生成一个带初始值的行编辑框 __init__(self, QString contents, QWidget parent = None)
方法:
- clear(self):清除编辑框内容;
- setText(self, QString):设置编辑框的内容;
- text(self):取编辑框内的文本内容;
- setMaxLength(self, int):设置编辑框能够输入的最大长度
3、文本编辑框 QTextEdit
# QTextEdit 类 logedit = QtGui.QTextEdit(widget)
信号:
- cursorPositionChanged():光标位置改变触发;
- textChanged(const QString&):文本内容改变时触发的信号;
构造方法:
# 生成一个文本编辑框 __init__(self, QWidget parent = None) # 生成一个有初始文本的文本编辑框 __init__(self, QString_text, QWidget parent = None)
方法:
- clear(self):清除编辑框内容;
- setText(self, QString):设置编辑框的内容;
- toPlainText(self):以文本的格式取编辑框内的文本内容;
- toHtml(self):以 HTML 的格式取编辑框内的文本内容;
4、标签 QLabel
userlabel = QtGui.QLabel('label', widget)
构造方法:
__init__(self, QWidget parent = None, Qt.WindowFlags flags = 0): # 带值的标签 __init__(self, QString_text, QWidget parent = None, Qt.WindowFlags flags = 0)
方法:
- clear(self):清除编辑框内容;
- setText(self, QString):设置编辑框的内容;
- text(self):取编辑框内的文本内容;
5、下拉框 QComboBox
# 得到下拉框对象 select_box= QtGui.QComboBox(widget)
信号:
- currentIndexChanged(int):选择项改变时触发,返回当前选项序号
- currentIndexChanged(const QString&):选择项改变时触发,返回当前选项文本
- activated(int):当用户选择下拉列表的项时触发,即使选择项未改变
- activated(const QString&):当用户选择下拉列表的项时触发,即使选择项未改变
构造方法:
__init__(self, QWidget parent = None)
方法:
- addItem(self, QString text, QVariant userData = QVariant()):给下拉列表添加下拉项;
- addItems(self, QStringList texts):给下拉列表添加多个下拉项;
- currentIndex(self):返回当前下拉列表的下拉项序号;
- currentText(self):返回当前下拉列表的下拉项文本;
- setItemText(self, int index, QString text):设置下拉项的文本
6、树结构 QTreeWidget
# 树结构对象 casetree = QtGui.QTreeWidget(self.centralwidget)
信号:
- itemClicked(QTreeWidgetItem*,int):选项被点击时触发
- itemCollapsed(QTreeWidgetItem*):子选项被隐藏时触发
- itemDoubleClicked(QTreeWidgetItem*,int):选项被双击时触发
- itemExpanded(QTreeWidgetItem*):子选项被展示时触发
构造方法:
__init__(self, QWidget parent = None)
方法:
- setColumnCount(self, int columns):设置树结构的列数;
- setHeaderLabels(self, QStringList labels):设置列标签;
- headerItem(self):返回用于树窗口小部件标题的项目;
7、树目录 QTreeWidgetItem
root= QtGui.QTreeWidgetItem(self.casetree)
构造方法:
__init__(self, int type = QTreeWidgetItem.Type) __init__(self, QStringList strings, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidget parent, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidget parent, QStringList strings, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidget parent, QTreeWidgetItem preceding, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidgetItem parent, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidgetItem parent, QStringList strings, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidgetItem parent, QTreeWidgetItem preceding, int type = QTreeWidgetItem.Type) __init__(self, QTreeWidgetItem other)
方法:
- addChild(self, QTreeWidgetItem child):添加子节点;
- checkState(self, int column):检查点击状态;
- setCheckState(self, int column, Qt.CheckState state):设置选项的选中状态,第二个参数为 QT.Checked 表示选中,Qt.UnChecked 表示未选中;
- setData(self, int column, int role, QVariant value):设置选项的角色值;
- setText(self, int column, QString atext):设置选项的文本内容
界面布局
这一块大家了解一下即可。基本上 GUI 界面都是通过绘图得到的。
1、绝对定位
用像素(px) 指定每个组件(控件) 的大小和位置。
# 使用 move 方法确定组件的位置 move(x, y) # 开始的两个参数是窗体的 x 和 y 的位置,a、b 为组件的宽度、高度 setGeometry(x, y, a, b)
2、框布局
基本的布局类是 QHBoxLayout 和 QVBoxLayout ,它们可以横向和纵向排列窗口组件。QHBoxLayout 布局类为水平布局类,在该布局中的组件呈水平排列。QVBoxLayout 布局类为垂直布局类,在该布局中的组件呈垂直排列。框布局就是结合水平布局与垂直布局,使组件能够二维分布
import sys from PyQt4 import QtGui class MainWindow(QtGui.QWidget): """docstring for ClassName""" def __init__(self, parent=None): super(MainWindow, self).__init__() self.initUI() def initUI(self): okButton = QtGui.QPushButton("OK") cancelButton = QtGui.QPushButton("Cancel") hbox = QtGui.QHBoxLayout() hbox.addStretch(1) hbox.addWidget(okButton) hbox.addStretch(1) hbox.addWidget(cancelButton) vbox = QtGui.QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) vbox.addStretch(1) self.setLayout(vbox) self.setWindowTitle('box layout') if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
3、网格布局
最常用的布局类是网格布局,网格布局把空间划分成行和列,一般使用 QGridLayout 类来创建网格布局。布局类型设置好以后使用 addWidget() 方法来把窗口组件加到网格中,参数是部件(widget),行(row)和列(column)数字。
- addWidget(widget-obj):给布局添加组件,将我们需要用到的控件加入到布局中;
- addLayout(Layout-obj):给布局添加另一个布局,使用框布局通常需要用该方法将水平布局和垂直布局结合;
代码实例:
import sys from PyQt4 import QtGui class MainWindow(QtGui.QWidget): """docstring for ClassName""" def __init__(self, parent=None): super(MainWindow, self).__init__() self.initUI() def initUI(self): self.setWindowTitle('grid layout') names = ['Cls', 'Bck', '', 'Close', '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', '.', '=', '+'] grid = QtGui.QGridLayout() j = 0 pos = [(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (3, 0), (3, 1), (3, 2), (3, 3 ), (4, 0), (4, 1), (4, 2), (4, 3)] for i in names: button = QtGui.QPushButton(i) if j == 2: grid.addWidget(QtGui.QLabel(''), 0, 2) else: grid.addWidget(button, pos[j][0], pos[j][1]) j = j + 1 self.setLayout(grid) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
GUI 页面
我们将利用 QtGui 模块实现生成 GUI 界面,学习常用的几个类。
实例一:学习了解几个方法
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui def main(): # 创建 app 对象,每个 PyQt 程序都必须创建一个 Application 对象 # sys.argv 获取参数列表 app = QtGui.QApplication(sys.argv) # w 为 QWidget 类的对象,QWidget 窗口组件是 PyQt4 所有用户界面的基类 w =QtGui.QWidget() # 初始化界面的大小,以下单位为像素(px) w.resize(250, 150) # 移动窗口的位置 w.move(300, 300) # 设置界面标题 w.setWindowTitle('Simple GUI') # 设置应用程序图标 w.setWindowIcon(QtGui.QIcon('icons/web.png')) # show() 方法将 GUI 界面显示在屏幕上 w.show() # 退出循环时,调用 exit() 方法关闭 sys.exit(app.exec_()) if __name__ == '__main__': main()
实例二:了解事件和 QMessageBox
# -*- coding: utf-8 -*- import sys from PyQt4 import QtGui class MainWindow(QtGui.QMainWindow): """主 GUI 界面窗口""" def __init__(self, parent=None): # 继承父类的构造方法,也可称之为超类 super(MainWindow, self).__init__() # setGeometry() 方法定义了窗体在屏幕上的位置,并设置窗体的大小。 # 开始的两个参数是窗体的 x 和 y 的位置,后面两个为 GUI 界面的宽度、高度 self.setGeometry(200,200,600,500) # 设置标题 self.setWindowTitle('test') # 气泡提示 self.setToolTip('This is a <b>QWidget</b> widget.') # 设置字体 # QtGui.QToolTip.setFont(QtGui.QFont('OldEnglish', 10)) def closeEvent(self, event): """ 关闭 GUI 界面时,将会产生一个 QCloseEvent 事件。 这里重写了 closeEvent 方法,实现关闭窗口时需要确认。改变了组件的行为。 """ reply = QtGui.QMessageBox.question(self,'Message','Are you sure to quit?',QtGui.QMessageBox.Yes,QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: event.accept() else: event.ignore() if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
实例三:
学习主 GUI 界面的状态栏、菜单栏、工具栏。工具栏一般不常用,常用的是另外两个。
注意:QMainWindow 类才有状态栏、菜单栏、工具栏。QWidget 与 QDialog 类型的窗口都不能这样使用。
# -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class MainWindow(QtGui.QMainWindow): """主 GUI 界面窗口""" def __init__(self, parent=None): # 继承父类的构造方法 super(MainWindow, self).__init__() self.resize(600,500) self.setWindowTitle('Test') # 调用 QMainWindow 的 statusBar() 方法得到状态栏 # 调用 showMessage() 方法显示状态信息 self.statusBar().showMessage('Ready') # 定义一个 exit 的动作,设置图标和名字 exit = QtGui.QAction(QtGui.QIcon(''),'Exit',self) # 设置动作的快捷键 exit.setShortcut('Ctrl+Q') # 状态栏显示 exit 动作提示信息 exit.setStatusTip('Exit the Application') # connect() 方法连接信号和槽函数 self.connect(exit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()')) # 调用 menuBar() 方法得到菜单栏 menu = self.menuBar() # 调用 addMenu() 方法得到菜单项 tools = menu.addMenu('&Tools') # 添加动作到菜单 tools.addAction(exit) # 通过 addToolBar() 方法得到工具栏,工具栏一般不常用。 self.toolbar = self.addToolBar('GoBack') #初始化一个动作 goback = QtGui.QAction(QtGui.QIcon(''),'goback',self) #设置动作的快捷方式 goback.setShortcut('Ctrl+D') #将动作添加到工具栏 self.toolbar.addAction(goback) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
事件、信号与槽
这部分是 PyQt 程序一个核心部分。开发 PyQt 程序必须要掌握理解以下概念
事件
事件(Events)是 GUI 程序中很重要的一部分。它由用户或系统产生。当我们调用程序的 exec_() 方法时,程序就会进入主循环中。主循环捕获事件并将它们发送给相应的对象进行处理,事件往往伴随着一个信号的发生,或一个信号的处理。
这里事件(Events)包括鼠标点击、键盘按键输入等事件。
#!/usr/bin/python # -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class KeyExample(QtGui.QWidget): def __init__(self): super(KeyExample, self).__init__() self.setWindowTitle('Escape') self.resize(500, 500) def keyPressEvent(self, event): if event.key() == QtCore.Qt.Key_Escape: self.close() if __name__ == "__main__": app = QtGui.QApplication(sys.argv) ex = KeyExample() ex.show() sys.exit(app.exec_())
信号与槽
当用户单击一个按钮,拖动一个滑块或进行其它动作时,相应的信号就会被触发。除此之外,信号还可以因为环境的变化而被发射。比如一个运行的时钟将会发射时间信号等。而所谓的槽则是一个方法(函数),该方法将会响应它所连接的信号。在 Python 中,槽可以是任何可以被调用的对象。槽一般为事件处理函数,专门用于处理某个信号。
在 PyQt 中,通过 connect() 方法连接信号与槽函数。此方法一般传入的参数为发送信号的对象、信号、对信号作出反应的方法(槽函数)。
connect(sender, QtCore.SIGNAL('clicked()'), revicer, QtCore.SLOT())
我们来看一个信号与槽的代码实例,目前我们用的最多就是 button 按钮的信号(clicked())。
# -*- coding: utf-8 -*- import sys from PyQt4 import QtGui, QtCore class ButtonExample(QtGui.QMainWindow): def __init__(self): super(ButtonExample, self).__init__() self.initUI() def initUI(self): button1 = QtGui.QPushButton("Button 1", self) button1.move(30, 50) button2 = QtGui.QPushButton("Button 2", self) button2.move(150, 50) # 连接信号与槽函数 self.connect(button1, QtCore.SIGNAL('clicked()'), self.buttonClicked) self.connect(button2, QtCore.SIGNAL('clicked()'), self.buttonClicked) self.statusBar().showMessage('Ready') self.setWindowTitle('Event sender') self.resize(290, 150) def buttonClicked(self): """自定义槽函数,对信号作出反应""" # sender() 方法获取产生信号的对象 sender = self.sender() self.statusBar().showMessage(sender.text() + ' was pressed') if __name__ == '__main__': app = QtGui.QApplication(sys.argv) button = ButtonExample() button.show() sys.exit(app.exec_())
自定义信号
当然,我们也可以自定义信号。自定义信号不仅可以用于改变页面的显示状态,还可用于 GUI 线程与逻辑线程之间的数据传递。
# 创建一个不传递参数的信号 self.mysignal = QtCore.SIGNAL('bigthan10()') # 使用 emit() 方法发送信号 self.emit(self.mysignal) # 创建一个传递参数的信号,参数类型为 int self.mysignal = QtCore.pyqtSignal(int) # 发送信号 self.mysignal.emit(20)
注意:使用自定义的槽函数处理自定义带传递参数的信号时,槽函数的参数与信号的参数必须保持一致(参数类型、参数个数、参数顺序)。
# -*- coding: utf-8 -*- import sys import time from PyQt4 import QtGui, QtCore class MainWindow(QtGui.QMainWindow): # 定义一个信号,信号不能定义在构造函数中,否则会报错 mysignal = QtCore.pyqtSignal(str) def __init__(self): super(MainWindow,self).__init__() self.setGeometry(100,100,500,500) self.setWindowTitle('test') #self.setWindowIcon(QtGui.QIcon('C:\Users\Administrator\cut.png')) self.statusbar =self.statusBar() #创建一个状态栏 self.mysignal.connect(self.statusMessage) #连接信号与槽函数 date =time.ctime() self.mysignal.emit(str(date)) #发射信号 def statusMessage(self,date): # 自定义槽函数 self.statusbar.showMessage("now is %s!"%date) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec_())
画图
此部分为开发 PyQt 程序的核心部分。
前面我们介绍了 GUI 界面的相关组件、以及如何通过代码实现得到一个 GUI 界面。对于简单的图形界面,我们可以通过编写源码实现。但是如果图形界面过于复杂时,此时通过编码方式生成图形界面,工作量是非常巨大。此时我们可以通过 PyQt 工具包的 Designer 工具设计图形界面,保存得到.ui 文件,然后通过命令得到此 GUI 界面的 python 源码。
pyuic4 gui.ui > gui.py
现场演示如何使用此工具。
Designer 工具
1、组件栏:显示组件,供用户选择
2、主界面栏:显示主界面,相当与一个画布,可以在上面设计我们需要的页面
3、对象编辑栏:包括几个部分
- 对象查看器:查看当前页面上存在的对象以及层次结构,显示对象名与对象类型,我们可以在这里修改对象名;
- 属性编辑器:用于编辑对象的属性信息,在页面或对象查看器上选择对象,然后在属性编辑器上就能查看或修改到该对象所拥有的属性;
- 资源浏览器:查看可用资源;
- 信号/槽编辑器:创建信号与槽的关系,可以指定到某个对象
- 动作编辑器:编辑动作,可添加到菜单栏或工具栏
import sys from PyQt4 import QtGui,QtCore from gui import Ui_MainWindow class MainWindoW(QtGui.QMainWindow): """导入 gui.py 得到图形界面""" def __init__(self): super(MainWindoW, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) wm = MainWindoW() wm.show() sys.exit(app.exec_())
多线程
此部分为图形化编程核心部分。
在 GUI 编程中,由于主界面是一个无限循环,且一直监听事务的发生,所以如果在主 UI 线程中做一些耗时的操作,会导致线程阻塞卡死,所以 PyQt 编程需要将主 UI 线程与逻辑线程分离,将一些耗时的操作都放在子线程里执行,主线程与子线程之间的数据传递通过自定义信号实现,PyQt 中定义的线程管理类为位于 QtCore 包的 QThread 类。
线程管理类 QThread
首先我们先学习 QThread 类有哪些方法。
1、信号
- finished() 当线程执行完成触发该信号
- started() 当线程开始时触发该信号
- terminated() 当线程被中断停止时触发该信号
2、方法
- __init__(self, QObject parent = None) parent 参数为父类线程的窗口类
- quit(self) 终止线程执行
- terminate(self) 终止线程,可能立即终止,也不能不会立即终止。
- wait(self, int msecs = ULONG_MAX) 线程睡眠,等待
- start(self) 拉起线程,并执行。
- run(self) 线程主体函数,调用 start() 方法后,便会执行 run() 方法中的代码。一般逻辑处理代码均写在 run() 函数中
- currentThread() 返回当前的线程对象
- currentThreadId() 返回当前线程 Id
线程之间数据传递
1、通过 PyQt 中信号与槽的机制传递数据。
2、通过自定义的公共配置文件传递数据(如 config.ini)。
编写一个子线程
继承 QThread 类,重写 run 方法。
代码实例如下:
# -*- coding: utf-8 -*- import sys, time from PyQt4 import QtGui, QtCore from PyQt4.QtGui import QPushButton, QLineEdit class TimeThread(QtCore.QThread): """工作线程""" # 自定义信号,指定参数类型为 str signal_time = QtCore.pyqtSignal(str) def __init__(self, parent=None): super(TimeThread, self).__init__(parent) def start_timer(self): self.start() def stop_timer(self): self.terminate() self.wait() def run(self): while True: print("Working", self.thread()) print(time.ctime(),type(time.ctime())) # 发送信号,并携带参数值 self.signal_time.emit(time.ctime()) self.sleep(1) class TimeWindow(QtGui.QMainWindow): def __init__(self): super(TimeWindow, self).__init__() self.init_ui() # 实例化子线程 self.timer_t = TimeThread() # 信号连接槽函数 self.timer_t.signal_time.connect(self.update_timer_tv) def init_ui(self): """生成 GUI 界面""" self.resize(300, 300) self.setWindowTitle('Time Clock') self.statusBar().showMessage('Ready') # 初始化行标签对象 self.timer_tv = QLineEdit(self) self.timer_tv.setText("Wait") self.timer_tv.setGeometry(15, 15, 270, 25) # self.timer_tv.move(15, 15) lable1 = QtGui.QLabel('Current Time',self) lable1.move(150,100) # 初始化设置 Quit 按键对象 stop_btn = QPushButton('Stop', self) stop_btn.setToolTip('Click to Stop') stop_btn.move(150, 150) # 连接 clicked 信号和槽函数 self.connect(stop_btn, QtCore.SIGNAL("clicked()"), self.click_stop_button) # 初始化设置 start 按键对象 start_btn = QPushButton('Start', self) start_btn.setToolTip("Click to start") start_btn.move(50, 150) # 连接 clicked 信号和槽函数 self.connect(start_btn, QtCore.SIGNAL("clicked()"), self.click_start_button) def click_start_button(self): """槽函数拉起执行子线程""" self.timer_t.start_timer() self.statusBar().showMessage('Go') def click_stop_button(self): """槽函数终止子线程""" self.timer_t.stop_timer() self.statusBar().showMessage('Ready') def update_timer_tv(self, text): # 槽函数 self.timer_tv.setText(text) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = TimeWindow() window.show() sys.exit(app.exec_())
开发 PyQt 程序
开发过程
- 确认需求
- 画图得到 gui.ui 文件,通过命令转换为 python 源码
- 编写主界面源码,得到界面
- 定义 config.ini 文件用来保存 GUI 界面的参数信息
- 编写后端代码(线程类)
- 连接信号和槽函数
- 调试运行
注意事项
- 安装 PyQt 时,注意版本之间的对应关系(包括位版本,如 32 位、64 位)。
- 编写线程代码时,注意线程卡死问题。
- GUI 界面参数传递到后台,注意参数的类型和值。一般的,都需要对参数进行处理。
(这里推荐 python 内置函数 eval())
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: Requests 模块方法总结
下一篇: 彻底找到 Tomcat 启动速度慢的元凶
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论