pyqt极速入门
安装
安装pyqt
pip install pyqt5
安装简化版qt designer
https://build-system.fman.io/qt-designer-download
qt designer
先用qt designer画框
然后将ui转为py代码
pyuic5 -o destination.py original.ui 
ui demo
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'C:\Users\david\Desktop\untitled.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(808, 508)
        self.textBrowser = QtWidgets.QTextBrowser(Form)
        self.textBrowser.setGeometry(QtCore.QRect(10, 230, 781, 291))
        self.textBrowser.setObjectName("textBrowser")
        self.groupBox = QtWidgets.QGroupBox(Form)
        self.groupBox.setGeometry(QtCore.QRect(10, 20, 781, 181))
        self.groupBox.setTitle("")
        self.groupBox.setObjectName("groupBox")
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(10, 30, 54, 12))
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(self.groupBox)
        self.pushButton.setGeometry(QtCore.QRect(454, 22, 71, 31))
        self.pushButton.setObjectName("pushButton")
        self.lineEdit = QtWidgets.QLineEdit(self.groupBox)
        self.lineEdit.setGeometry(QtCore.QRect(90, 20, 291, 31))
        self.lineEdit.setObjectName("lineEdit")
        self.pushButton_2 = QtWidgets.QPushButton(self.groupBox)
        self.pushButton_2.setGeometry(QtCore.QRect(540, 20, 81, 31))
        self.pushButton_2.setObjectName("pushButton_2")
        self.label_2 = QtWidgets.QLabel(Form)
        self.label_2.setGeometry(QtCore.QRect(10, 210, 54, 12))
        self.label_2.setObjectName("label_2")
        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "script boy tools"))
        self.label.setText(_translate("Form", "url"))
        self.pushButton.setText(_translate("Form", "attack"))
        self.pushButton_2.setText(_translate("Form", "stop"))
        self.label_2.setText(_translate("Form", "log"))
将designer.py和编写逻辑的py放在同一目录,以便引用
test.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from designer import Ui_Form
class Demo(QWidget, Ui_Form):
    def __init__(self):
        super(Demo, self).__init__()
        self.setupUi(self)                                          # 1
        self.text_edit.textChanged.connect(self.show_text_func)     # 2
    def show_text_func(self):
        self.text_browser.setText(self.text_edit.toPlainText())
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())
将UI界面布局到Demo上;
将self.text_edit的textChanged信号连接到自定义的槽函数上,在槽函数中我们将self.text_browser的文本设为self.text_edit的文本。
signal和slot
pyqt核心就是信号和槽,用来传递指令和执行指令
控件有很多属性,比如说按钮被点击,点击就是一种信号,可以连接槽函数来执行内容
这是一个信号连接一个槽连接的例子
还有多个信号连接一个槽、信号连接信号、一个信号连接多个槽、自定义信号
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
class Demo(QWidget):                                            # 1
    def __init__(self):
        super(Demo, self).__init__()
        self.button = QPushButton('Start', self)                # 2
        self.button.clicked.connect(self.change_text)           # 3
    def change_text(self):
        print('change text')
        self.button.setText('Stop')                             # 4
        self.button.clicked.disconnect(self.change_text)        # 5
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()                                               # 6
    demo.show()                                                 # 7
    sys.exit(app.exec_())
在线程中获取窗口内容
ui线程只能用来跑ui,要执行业务逻辑得多开一个线程,防止窗口阻塞
获取输入框的内容
import sys
from PyQt5.QtCore import QThread
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit, QLabel, QVBoxLayout, QHBoxLayout
class Demo(QWidget):
    def __init__(self):
        super(Demo, self).__init__()
        self.line = QLineEdit()
        self.btn = QPushButton('开始爬取')
        self.btn.clicked.connect(self.start_slot)
        h_layout = QHBoxLayout()
        v_layout = QVBoxLayout()
        h_layout.addWidget(QLabel('网址:'))
        h_layout.addWidget(self.line)
        v_layout.addLayout(h_layout)
        v_layout.addWidget(self.btn)
        self.setLayout(v_layout)
        self.crawl_thread = CrawlThread(self)  # 1
    def start_slot(self):  # 2
        self.crawl_thread.start()
class CrawlThread(QThread):
    def __init__(self, demo):  # 3
        super(CrawlThread, self).__init__()
        self.demo = demo
    def run(self):  # 4
        url = self.demo.line.text().strip()
        print(f'要爬取的网址为:{url}')
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())
实例化线程,注意此时我们需要把当前窗口类实例(也就是self)传入。
按钮所连接的槽函数用来启动线程。
给线程的初始化函数添加一个参数,用来获取窗口类实例。
接着我们就可以在run函数中获取窗口上任何一个控件及其内容了。
子线程数据输入到控件
这里发起请求包的子线程的返回值输出到textbrowser控件上,txetbrowser就变成一个打印日志的框
用到了自定义信号来实现线程间通信
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from destination import Ui_Form
import requests
from PyQt5.QtCore import Qt, QThread, pyqtSignal
class Demo(QWidget, Ui_Form):
    def __init__(self):
        super(Demo, self).__init__()
        self.setupUi(self)  
        self.pushButton.clicked.connect(self.login)
        self.my_thread = MyThread(self) # 1
        self.my_thread.child_signal.connect(self.log) # 2
    def log(self, msg): # 5
        self.textBrowser.append(msg)
        # self.textBrowser.setText(msg)
    def login(self):
        self.my_thread.start()
class MyThread(QThread):
    child_signal = pyqtSignal(str)  # 3
    def __init__(self, demo):
        super(MyThread, self).__init__()
        self.demo = demo
    def buy(self):
        print('buy')
    def run(self): 
        # phone = self.demo.textEdit.toPlainText()
        # print(phone)
        while 1:
            res=requests.get("http://www.baidu.com")
        # self.demo.textBrowser.setText(phone)
        # self.sig.emit(phone)
            self.child_signal.emit(res.text) # 4
class Send(QThread):
    pass
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = Demo()
    demo.show()
    sys.exit(app.exec_())
- 实例化线程对象
 - 线程自定义信号连接槽函数
 - 自定义信号对象,str表示这个信号可以传递一个参数
 - 自定义信号将结果发射出去
 - 结果传递给槽函数