Python自动化(8)——pyqt5界面
注意:pyqt5的界面使用时必须有app = QApplication(sys.argv)这行代码,否则会出现错误并且无法显示窗口:QWidget: Must construct a QApplication before a QWidget
一些基础的控件
QMainWindow
QMainWindow是PyQt5中一个重要的类,它提供了一个主窗口的框架,可以包含菜单栏、工具栏、状态栏以及中心部件等。
常用的方法有:
setMenuBar(self, QMenuBar): 设置菜单栏。
menuBar(self) -> QMenuBar: 获取菜单栏。
addToolBar(self, QToolBar): 添加工具栏。
statusBar(self) -> QStatusBar: 获取状态栏。
setStatusBar(self, QStatusBar): 设置状态栏。
setCentralWidget(self, QWidget): 设置中心部件。
centralWidget(self) -> QWidget: 获取中心部件。
addDockWidget(self, Qt.DockWidgetArea, QDockWidget): 添加停靠窗口。
QtCore.pyqtSignal
pyqtSignal是PyQt5中用于定义和发射信号的类。信号是Qt框架中事件驱动机制的核心部分,通过信号和槽机制,可以在对象之间进行通信。
下面的例子中,就使用了pyqtSignal实现日志的显示。
QTabWidget
QTabWidget是PyQt5中用于创建选项卡界面的一个控件。
QWidget
QWidget是PyQt5中所有用户界面对象的基类,它提供了一个窗口部件的基本功能,并且可以作为一个容器来包含其它窗口部件。
QHBoxLayout和QVBoxLayout
QHBoxLayout 和 QVBoxLayout 是 PyQt5 中用于管理窗口部件布局的两种常见布局管理器。它们分别用于水平和垂直排列窗口部件。
QPushButton
QPushButton 是 PyQt5 中的一个常用窗口部件,用于创建按钮。
QListWidget和QListWidgetItem
QListWidget 是 PyQt5 中的一个常用窗口部件,用于显示和管理列表项。列表项类就是QListWidgetItem,它可以包含文本、图标、工具提示等信息。
QLabel
QLabel 是 PyQt5 中的一个常用控件,用于显示文本或图像。
QCheckBox
QCheckBox 是 PyQt5 中的一个控件,用于在用户界面中显示一个复选框。用户可以通过点击复选框来选择或取消选择某个选项。QCheckBox 可以用于多选项的选择,也可以用于单选项的开关。
QLineEdit
QLineEdit 是 PyQt5 中的一个控件,用于单行文本输入。它提供了多种方法和属性来处理文本输入、验证、格式化等功能。
以上都是比较常用的pyqt5控件,其实还有部分可重写的方法例如closeEvent,会在窗口关闭时调用,还有许多事件可重写,如下图:
实现一个简单的pyqt5界面
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout
from PyQt5.QtWidgets import QTabWidget, QPushButton, QListWidget, QLabel, QListWidgetItem
from PyQt5 import QtCore
from threading import Threadclass Window(QMainWindow):pysignal = QtCore.pyqtSignal(str)def __init__(self):super().__init__()self.taskList = []self.logList = []self.logIndex = 1self.pysignal.connect(self.onCallSignal)self.setWindowTitle("简单的pyqt5界面")self.setGeometry(100, 100, 800, 600)self.tab_widget = QTabWidget()self.setCentralWidget(self.tab_widget)self.create_login_tab()self.create_task_tab()self.create_hint_tab()def create_login_tab(self):login_tab = QWidget()layout = QVBoxLayout()login_button = QPushButton("登陆")layout.addWidget(login_button)login_tab.setLayout(layout)self.tab_widget.addTab(login_tab, "登陆")def create_task_tab(self):task_tab = QWidget()main_layout = QHBoxLayout()left_layout = QVBoxLayout()right_layout = QVBoxLayout()# Left side layoutself.taskListView = QListWidget()self.logListView = QListWidget()left_layout.addWidget(self.taskListView)left_layout.addWidget(self.logListView)# Right side layoutcreate_task_button = QPushButton("创建任务")start_task_button = QPushButton("开始任务")end_task_button = QPushButton("结束任务")delete_task_button = QPushButton("删除任务")show_log_button = QPushButton("显示log")clear_log_button = QPushButton("清空log")create_task_button.clicked.connect(self.createThread)start_task_button.clicked.connect(self.startTask)end_task_button.clicked.connect(self.stopTask)show_log_button.clicked.connect(self.showLog)clear_log_button.clicked.connect(self.clearLog)right_layout.addWidget(create_task_button)right_layout.addWidget(start_task_button)right_layout.addWidget(end_task_button)right_layout.addWidget(delete_task_button)right_layout.addWidget(show_log_button)right_layout.addWidget(clear_log_button)main_layout.addLayout(left_layout)main_layout.addLayout(right_layout)task_tab.setLayout(main_layout)self.tab_widget.addTab(task_tab, "任务")def create_hint_tab(self):hint_tab = QWidget()layout = QVBoxLayout()hint_label = QLabel("本软件仅供学习")layout.addWidget(hint_label)hint_tab.setLayout(layout)self.tab_widget.addTab(hint_tab, "提示")def createThread(self):index = len(self.taskList)+1item = QListWidgetItem('任务'+str(index))item.setData(1, index-1)self.taskListView.addItem(item)task = Task(self.showLog)self.taskList.append(task)def onCallSignal(self, content):item = QListWidgetItem(content)self.logListView.addItem(item)if self.logListView.currentRow() == self.logListView.count()-2:self.logListView.setCurrentRow(self.logListView.count()-1)self.logListView.scrollToBottom()def showLog(self, content):if not content:content = str(self.logIndex)self.logIndex += 1self.pysignal.emit(content)def clearLog(self):self.logListView.clear()def getCurrentIndex(self):curItem = self.taskListView.currentItem()if curItem:index = curItem.data(1)return indexelse:return -1def _startTask(self, index):if -1 < index < len(self.taskList):self.taskList[index].start()self.showLog('开始任务 index: ' + str(index))def startTask(self):index = self.getCurrentIndex()thread = Thread(target=self._startTask,args=(index,))thread.start()def _stopTask(self, index):if -1 < index < len(self.taskList):if self.taskList[index].isRunning():self.taskList[index].terminate()self.showLog('结束任务 index: ' + str(index))def stopTask(self):index = self.getCurrentIndex()thread = Thread(target=self.show)thread.start()class Task(QtCore.QThread):def __init__(self, logCallback):super().__init__()self.callback = logCallbackdef show(self):for i in range(10):self.callback(str('task running ' + str(i)))self.sleep(1)def run(self):thread = Thread(target=self.show)thread.start()def main():app = QApplication(sys.argv)window = Window()window.show()sys.exit(app.exec_())if __name__ == "__main__":main()
效果:
这里有一点需要注意,就是开始任务和结束任务等需要一定的时间的操作,我一般都需要使用线程来执行。如果不使用线程执行耗时任务,那么任务有可能会卡住主线程,从而使界面卡死。
完整自动化工程代码:https://gitee.com/chj-self/PythonRobotization
大佬们找到问题欢迎拍砖~