ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PyQt5简单开发

2019-12-06 17:00:42  阅读:261  来源: 互联网

标签:__ task self PyQt5 init 开发 QMessageBox 简单 def


1.窗口类型

QMainWindow:可以包含菜单栏、工具栏、标题栏、状态栏,是最常见的窗口形式

QWidgets:不确定窗口的用途,使用QWidgets

QDialog:对话窗口的基类,用于执行短期任务,没有菜单栏、工具栏、状态栏

2.创建窗体应用程序

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication


class MainWin(QMainWindow):
    def __init__(self):
        super(MainWin, self).__init__()

        self.setWindowTitle("抓取工具")

        self.resize(400, 300)
        self.status = self.statusBar()
        self.status.showMessage('抓取工具')


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mainWin = MainWin()
    mainWin.show()

    sys.exit(app.exec_())

从Main中可知,创建窗体程序,先要创建QApplication对象即应用对象,然后创建窗口对象(继承自三种窗口类型),然后调用窗口的显示函数show(),注意:没有show函数,运行时指挥创建相关进程,即用用程序,窗口不显示,唯有调用show函数,窗口才会显示。

3.在窗体创建控件对象

按钮、输入框、标签等控件基本上都在QtWidgets类中,添加控件代码示例

class MainWin(QMainWindow):
    path = './app_icon.cio'

    def __init__(self):
        super(MainWin, self).__init__()
        self.init_ui()

    # 界面初始化
    def init_ui(self):
        # 创建控件对象
        self.edit_name = QtWidgets.QLineEdit()
        self.btn = QtWidgets.QPushButton('退出')
        # 创建布局
        layout = QHBoxLayout()
        # 往布局中添加控件
        layout.addWidget(self.btn)
        layout.addWidget(self.edit_name)

        self.btn.clicked.conect(self.btn_click)
        # 把布局放到窗口上
        mainFrame = QtWidgets.QWidget()
        mainFrame.setLayout(layout)
        # 居中充满屏幕
        self.setCentralWidget(mainFrame)
        # 设置图标
        self.setWindowIcon(QIcon(self.path))

        self.setWindowTitle("窗体程序")
        self.resize(400, 300)
        self.status = self.statusBar()
        self.status.showMessage('状态栏')

 4.使用QtDesigner进行界面设计

1.配置PyCharm相关开发环境,下载安装相关包,pyqt5以及pyqt5-tools。然后在Pycharm中ExtenalTools中添加

 

 

 

 

QtDesigner路径:$Python安装路径$\Lib\site-packages\pyqt5_tools\Qt\bin\designer.exe,工作空间:$ProjectFileDir$

PyUIC路径:Python.exe路径,工作空间:$FileDir$,参数变量:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py

二者使用时请在Tools -》 ExtenalTools下选择

2.打开QtDesigner设计UI文件,选中UI文件使用PyUIC将其转为Pyton文件。

3.使用UI文件

UI类

from PyQt5 import QtCore, QtGui, QtWidgets


# UI执行窗口界面
class Ui_ExecWindow(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.process_display = QtWidgets.QTextBrowser(Form)
        self.process_display.setGeometry(QtCore.QRect(50, 50, 300, 200))
        self.process_display.setObjectName("process_display")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))

窗口类

class ExecWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.ui = Ui_ExecWindow()
        self.ui.setupUi(self)

建议二者分开,添加槽和信号的绑定可以在窗口类的初始化函数中书写。例如:

class ConfWindow1(QDialog):
    def __init__(self, task_type):
        QDialog.__init__(self)
        self.ui = Ui_ConfWindow1()
        self.ui.setupUi(self)
        self.new_actions = list()
        self.task_type = task_type  # 任务类型
        # 信号与槽绑定
        self.ui.rbtn_b.toggled.connect(self.input_type)
        self.ui.btn_save.clicked.connect(self.save_configuration)
        self.ui.btn_save_single.clicked.connect(self.save_single_action)

ui是UI类的实例对象。

5.PyQt中多线程处理,解决界面假死问题

当界面要执行一个耗时间较长的任务时,使用单线程会出现界面假死现象。使用多线程可以解决,模板如下

线程子类

# 多线程,执行任务
from PyQt5 import QtCore
from PyQt5.QtCore import QThread
from selenium import webdriver

from application_task.Task import Task
from customize_exception.CustomizeException import NoSuchSelectorError
from utils import Util


class Task_Excutor(QThread):
    _signal = QtCore.pyqtSignal(str)  # 自定义信号

    def __init__(self, task_type):
        super().__init__()
        self.task_type = task_type

    def __del__(self):
        self.wait()

    def run(self):
        driver = webdriver.Chrome()
        actions = []
        task_conf = {}
        # 出现异常传递信号,因为当前线程无法使用GUI
        try:
            actions = Util.json_2_element_actions(
                "./configuration/" + self.task_type + "动作配置.json")
            task_conf = Util.load_conf("./configuration/" + self.task_type + "杂项配置.json")
        except FileNotFoundError as e:
            self._signal.emit(str("e"))
        except NoSuchSelectorError as e1:
            self._signal.emit(str("e1"))
        except Exception as e2:
            self._signal.emit(str("e2"))
        else:
            try:
                task = Task(driver, actions, task_conf)
                task.original_task()
            except Exception as e3:
                self._signal.emit(str("e3"))
            else:
                # 成功信号
                self._signal.emit(str("succeed"))

界面调用类

 # 任务开始
    def start_task(self):
        self.thread = Task_Excutor(self.ui.task_selector.currentText())
        self.thread._signal.connect(self.call_back)
        self.thread.start()

    # 信号回调处理
    def call_back(self, msg):
        if msg == "e":
            QMessageBox(QMessageBox.NoIcon, '错误', '指定路径下配置文件不存在').exec()
        elif msg == "e1":
            QMessageBox(QMessageBox.NoIcon, '错误', '配置文件出错,没有指定的选择器').exec()
        elif msg == "e2":
            QMessageBox(QMessageBox.NoIcon, '错误', '未知错误,执行过程中出错').exec()
        elif msg == "e3":
            QMessageBox(QMessageBox.NoIcon, '错误', '未知错误,初始化动作或配置失败').exec()
        elif msg == 'succeed':
            QMessageBox(QMessageBox.NoIcon, '提示', '任务执行成功').exec()
        else:
            QMessageBox(QMessageBox.NoIcon, '提示', '未知线程回调消息').exec()

创建一个线程的子类,重写run方法。并定义信号,调用该线程的界面类中添加开始线程的方法start_task(),并与触发线程开始的事件绑定。start_task()方法中为自定义信号绑定方法call_back,用于处理创建的线程的执行任务过程中信号传递处理。

注意:由于pyqt中,非GUI线程是无法调用控件的,如在执行任务中实例化QMessageBox会出现错误导致程序异常退出。所以通过回调函数触发指定的信号并传递到GUI线程中进行控件的处理。

标签:__,task,self,PyQt5,init,开发,QMessageBox,简单,def
来源: https://www.cnblogs.com/higerMan/p/11982387.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有