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 Thread
class Window(QMainWindow):
pysignal = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.taskList = []
self.logList = []
self.logIndex = 1
self.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 layout
self.taskListView = QListWidget()
self.logListView = QListWidget()
left_layout.addWidget(self.taskListView)
left_layout.addWidget(self.logListView)
# Right side layout
create_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)+1
item = 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 += 1
self.pysignal.emit(content)
def clearLog(self):
self.logListView.clear()
def getCurrentIndex(self):
curItem = self.taskListView.currentItem()
if curItem:
index = curItem.data(1)
return index
else:
return -1
def _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 = logCallback
def 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
大佬们找到问题欢迎拍砖~