PyQt——结合Python与Qt的GUI编程

来源:互联网 发布:网络维护维修预算 编辑:程序博客网 时间:2024/05/14 11:31

PyQt是Python下的另一套图形界面接口库,顾名思义就是在Python中调用Qt图形库和组件。使用PyQt的优点在于可以使用Qt成熟的IDE(如Qt Creator)进行图形界面设计,并自动生成可执行的Python代码。

1.1.PyQt的安装和使用

PyQt可以通过apt-get命令安装,其对应Python 2.x 和Python 3.x的包名称不同。

安装Python 2.x下的PyQt:

查看原代码
$ sudo apt-get install python-pyqt4 pyqt4-dev-tools

安装Python 3.x下的PyQt:

查看原代码
  1. $ sudo apt-get install python3-pyqt4 pyqt4-dev-tools

获取PyQt的文档和范例程序(非必须):

查看原代码
  1. $ sudo apt-get install python-qt4-doc

获取到的范例程序保存在/usr/share/doc/python-qt4-doc/examples目录下找到。

2D绘图

对话框演示

FTP客户端(网络编程)演示

OpenGL 3D绘图

下面我们通过一段代码演示PyQt的使用。新建Python文件,命名为hello_pyqt.py,代码内容如下:

查看原代码
  1. import sys
  2. from PyQt4 import QtCore, QtGui
  3. class HelloPyQt(QtGui.QWidget):
  4. def __init__(self, parent = None):
  5. super(HelloPyQt, self).__init__(parent)
  6. self.setWindowTitle("PyQt Test")
  7. self.textHello = QtGui.QTextEdit("This is a test program written in python with PyQt lib!")
  8. self.btnPress = QtGui.QPushButton("Press me!")
  9. layout = QtGui.QVBoxLayout()
  10. layout.addWidget(self.textHello)
  11. layout.addWidget(self.btnPress)
  12. self.setLayout(layout)
  13. self.btnPress.clicked.connect(self.btnPress_Clicked)
  14. def btnPress_Clicked(self):
  15. self.textHello.setText("Hello PyQt!\nThe button has been pressed.")
  16. if __name__=='__main__':
  17. app = QtGui.QApplication(sys.argv)
  18. mainWindow = HelloPyQt()
  19. mainWindow.show()
  20. sys.exit(app.exec_())

在本例中,所有的PyQt控件都封装在HelloPyQt类中。首先添加了一个QTextEdit 控件textHello和QPushButton控件btnPress,然后通过self.btnPress.clicked.connect()语句将btnPress按钮的clicked信号连接至btnPress_Clicked()函数。

如此当按钮被按下时,会触发clicked事件,进而调用btnPress_Clicked()函数。该函数的功能就是改变textHello中的文本。

在Python3下运行程序:

查看原代码
  1. $ python3 hello_pyqt.py

PyQt程序运行效果

从上面的例子可以看出手动编写代码调用PyQt依然十分不便,好在PyQt还为我们准备了Qt GUI界面的转换工具,可以将Qt Creator生成的.ui文件直接转换成Python代码。比如需要对test.ui进行转换,其命令如下:

$ pyuic4 test.ui -x -o test.py

其中-x参数相当于--execute,在代码中增加了一些测试语句,这样生成的Python文件就可以直接执行了。之后我们就可以在生成的代码基础上实现自己的功能。

1.2.例:通过PyQt设计CPU温度监控软件

这里我们将通过PyQt设计一个监控树莓派内核温度的小软件。首先打开QtCreator,新建一个Qt GUI应用程序工程(如何在树莓派2本地安装运行Qt Creator,请参见:编程篇(一)在树莓派2上本地开发Qt GUI程序)。设计如下图所示的窗口界面:

在Qt Creator中设计GUI

通过pyuic命令将GUI文件转换成Python文件,然后在此基础上进行修改,代码如下:

查看原代码
  1. from PyQt4 import QtCore, QtGui
  2. import os
  3. try:
  4. _fromUtf8 = QtCore.QString.fromUtf8
  5. except AttributeError:
  6. _fromUtf8 = lambda s: s
  7. class Ui_HelloPyQt(object):
  8. def setupUi(self, HelloPyQt):
  9. HelloPyQt.setObjectName(_fromUtf8("HelloPyQt"))
  10. HelloPyQt.resize(304, 212)
  11. self.centralWidget = QtGui.QWidget(HelloPyQt)
  12. self.centralWidget.setObjectName(_fromUtf8("centralWidget"))
  13. self.lcdTemp = QtGui.QLCDNumber(self.centralWidget)
  14. self.lcdTemp.setGeometry(QtCore.QRect(40, 40, 221, 81))
  15. self.lcdTemp.setSmallDecimalPoint(False)
  16. self.lcdTemp.setDigitCount(6)
  17. self.lcdTemp.setObjectName(_fromUtf8("lcdTemp"))
  18. self.sliderAlarm = QtGui.QSlider(self.centralWidget)
  19. self.sliderAlarm.setGeometry(QtCore.QRect(40, 170, 221, 16))
  20. self.sliderAlarm.setMaximum(120)
  21. self.sliderAlarm.setProperty("value", 80)
  22. self.sliderAlarm.setOrientation(QtCore.Qt.Horizontal)
  23. self.sliderAlarm.setTickPosition(QtGui.QSlider.NoTicks)
  24. self.sliderAlarm.setObjectName(_fromUtf8("sliderAlarm"))
  25. self.labelAlarm = QtGui.QLabel(self.centralWidget)
  26. self.labelAlarm.setGeometry(QtCore.QRect(40, 150, 221, 16))
  27. self.labelAlarm.setObjectName(_fromUtf8("labelAlarm"))
  28. self.labelTemp = QtGui.QLabel(self.centralWidget)
  29. self.labelTemp.setGeometry(QtCore.QRect(40, 20, 221, 16))
  30. self.labelTemp.setObjectName(_fromUtf8("labelTemp"))
  31. #Add timer
  32. self.timerTemp = QtCore.QTimer(self.centralWidget)
  33. HelloPyQt.setCentralWidget(self.centralWidget)
  34. # Add slots
  35. self.sliderAlarm.valueChanged.connect(self.sliderAlarm_ValueChanged)
  36. self.timerTemp.timeout.connect(self.timerTemp_TimeOut)
  37. # Use the timeout event to initialize the LCD
  38. self.timerTemp_TimeOut()
  39. # Start timer, time out per 2 seconds
  40. self.timerTemp.start(2000)
  41. self.retranslateUi(HelloPyQt)
  42. QtCore.QMetaObject.connectSlotsByName(HelloPyQt)
  43. def retranslateUi(self, HelloPyQt):
  44. HelloPyQt.setWindowTitle(QtGui.QApplication.translate("HelloPyQt", "HelloPyQt", None, QtGui.QApplication.UnicodeUTF8))
  45. self.labelAlarm.setText(QtGui.QApplication.translate("HelloPyQt", "Alarm: 80C", None, QtGui.QApplication.UnicodeUTF8))
  46. self.labelTemp.setText(QtGui.QApplication.translate("HelloPyQt", "CPU Temperature", None, QtGui.QApplication.UnicodeUTF8))
  47. # Event triggered when the value of labelAlarm changed
  48. def sliderAlarm_ValueChanged(self):
  49. self.labelAlarm.setText("Alarm: " + str(self.sliderAlarm.value()) + "C")
  50. # Event triggered when timerTemp time out
  51. def timerTemp_TimeOut(self):
  52. # Get temperature from sensor file
  53. sensor = os.popen("cat /sys/class/thermal/thermal_zone0/temp")
  54. temp = float(sensor.readline()) / 1000
  55. alarm = float(self.sliderAlarm.value())
  56. # Display temperature
  57. self.lcdTemp.display("%.1fC" % temp)
  58. # Check whether the temperature is too high
  59. if temp <= alarm * 0.6:
  60. self.lcdTemp.setStyleSheet("color: green")
  61. elif temp <= alarm * 0.8:
  62. self.lcdTemp.setStyleSheet("color: orange")
  63. elif temp <= alarm:
  64. self.lcdTemp.setStyleSheet("color: red")
  65. else:
  66. self.lcdTemp.setStyleSheet("color: red")
  67. msg = QtGui.QMessageBox()
  68. msg.setWindowTitle("Alarm")
  69. msg.setText("Temperature is too high!")
  70. msg.setIcon(QtGui.QMessageBox.Warning)
  71. msg.exec_()
  72. # You can do something else here, like shut down the system
  73. if __name__ == "__main__":
  74. import sys
  75. app = QtGui.QApplication(sys.argv)
  76. HelloPyQt = QtGui.QMainWindow()
  77. ui = Ui_HelloPyQt()
  78. ui.setupUi(HelloPyQt)
  79. HelloPyQt.show()
  80. sys.exit(app.exec_())

代码中新建了一个QTimer定时器控件,用于定时查询CPU当前的温度并更新显示。self.timerTemp.timeout.connect()语句将定时器的超时信号链接至timerTemp_TimeOut()函数。self.timerTemp.start(2000)设置定时器超时时间为200ms,即每2秒执行一次timerTemp_TimeOut()函数。

LCD控件用于显示CPU当前的温度。在显示界面和运行定时器之前,可以通过手动调用self.timerTemp_TimeOut()函数读取CPU温度来初始化LCD控件内容。

CPU的温度通过读取 /sys/class/thermal/thermal_zone0/temp文件内容获得。这里采用os.popen()方法在Linux Shell中通过cat命令读取文件,并将返回的字符串信息转换为数字显示在LCD控件中。

窗口下面的滚动条用于设置温度报警门限,如果CPU温度接近门限值,则会改变温度显示的颜色。如果超过门限值则弹出对话框报警。

温度监控程序运行效果

这里我们还可以使用一个小程序将CPU占用率提高到100%来提升CPU温度,只要编写一段死循环的运算代码即可(一个Python进程只能在单个内核上运行,对于树莓派2,需要同时启动4个进程才能跑满全部内核)。代码内容如下:

查看原代码
  1. while True:
  2. a = 1298/1412

多进程后台执行:

查看原代码
  1. $ python tst.py&
  2. $ python tst.py&
  3. $ python tst.py&
  4. $ python tst.py&

提高CPU占用率

0 0