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表示这个信号可以传递一个参数
- 自定义信号将结果发射出去
- 结果传递给槽函数