简单的来说,信号与槽可以理解成是你说话,我回话,你不说话,我也不bb这种形式。
PyQt自带的信号与槽写法如下:
self.btn_DownloadSingleLink.clicked.connect(self.DownloadSingleLink)
此处的含义是按钮的点击事件的绑定
这个比较好理解,因为自带的,所以不需要自己设定信号事件
接下来简单说一下自定义信号事件的申明
首先,需要引入两个库from PyQt5.QtCore import pyqtSignal,QObject
一个是信号类,一个是基类
定义信号比较简单
在基类下定义类属性重点是类属性,而不是在init初始化下方法属性,不然会报错。
class Ui_MainWindow(QObject):
signal_single_link = pyqtSignal(str,str,str) #定义下载单条链接的信号参数(文件名,文件大小,文件进度)
def __init__(self):
self.download_url = ''
super(Ui_MainWindow, self).__init__()
在这边类里面,定义了signal_single_link这个信号,需要传递的参数是三个str类型的参数。
第二步时绑定槽,就很像你说话,总不能对着空气说,这样很无聊。
绑定槽函数的方法比较常见。
像这样。
self.signal_single_link.connect(self.showSingalInfo)
这个代码的含义就是绑定了showSignalInfo方法。
第三步 就是发送消息给槽。用的是emit
方法
就像这样
self.signal_single_link.emit(str(name),str(file_size),str(formatFloat(p)))
完整的代码如下
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ZL.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QMessageBox,QFileDialog
import time
import requests
import _thread
from PyQt5.QtGui import *
from PyQt5.QtCore import pyqtSignal,QObject
def convertCookie(cookie_val):
# 转成字典格式
return dict(map(lambda x: x.split('='), cookie_val.split(";")))
def formatFloat(num):
return '{:.2f}'.format(num)
class Ui_MainWindow(QObject):
signal_single_link = pyqtSignal(str,str,str) #定义下载单条链接的信号参数(文件名,文件大小,文件进度)
def __init__(self):
self.download_url = ''
super(Ui_MainWindow, self).__init__()
#定义测试信号
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(700, 600)
MainWindow.setMinimumSize(QtCore.QSize(700, 600))
MainWindow.setMaximumSize(QtCore.QSize(700, 600))
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
MainWindow.setFont(font)
MainWindow.setStyleSheet("")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 681, 41))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setSpacing(10)
self.horizontalLayout.setObjectName("horizontalLayout")
self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.label.setFont(font)
self.label.setObjectName("label")
self.horizontalLayout.addWidget(self.label)
self.lineEdit_Cookies = QtWidgets.QLineEdit(self.horizontalLayoutWidget)
self.lineEdit_Cookies.setEnabled(True)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.lineEdit_Cookies.setFont(font)
self.lineEdit_Cookies.setObjectName("lineEdit_Cookies")
self.horizontalLayout.addWidget(self.lineEdit_Cookies)
self.horizontalLayoutWidget_2 = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(10, 60, 681, 41))
self.horizontalLayoutWidget_2.setObjectName("horizontalLayoutWidget_2")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_2)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.label_2 = QtWidgets.QLabel(self.horizontalLayoutWidget_2)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
self.horizontalLayout_2.addWidget(self.label_2)
self.lineEdit_SingleLink = QtWidgets.QLineEdit(self.horizontalLayoutWidget_2)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.lineEdit_SingleLink.setFont(font)
self.lineEdit_SingleLink.setStyleSheet("")
self.lineEdit_SingleLink.setObjectName("lineEdit_SingleLink")
self.horizontalLayout_2.addWidget(self.lineEdit_SingleLink)
self.btn_DownloadSingleLink = QtWidgets.QPushButton(self.horizontalLayoutWidget_2)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.btn_DownloadSingleLink.setFont(font)
self.btn_DownloadSingleLink.setObjectName("btn_DownloadSingleLink")
self.btn_DownloadSingleLink.clicked.connect(self.DownloadSingleLink)
self.horizontalLayout_2.addWidget(self.btn_DownloadSingleLink)
self.horizontalLayoutWidget_3 = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget_3.setGeometry(QtCore.QRect(10, 110, 681, 41))
self.horizontalLayoutWidget_3.setObjectName("horizontalLayoutWidget_3")
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_3)
self.horizontalLayout_3.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.label_3 = QtWidgets.QLabel(self.horizontalLayoutWidget_3)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.horizontalLayout_3.addWidget(self.label_3)
self.btn_OpenTxtPath = QtWidgets.QPushButton(self.horizontalLayoutWidget_3)
self.btn_OpenTxtPath.setObjectName("btn_OpenTxtPath")
self.horizontalLayout_3.addWidget(self.btn_OpenTxtPath)
self.label_txt_path = QtWidgets.QLabel(self.horizontalLayoutWidget_3)
self.label_txt_path.setObjectName("label_txt_path")
self.horizontalLayout_3.addWidget(self.label_txt_path)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(spacerItem)
self.btn_SetThreadNum = QtWidgets.QPushButton(self.horizontalLayoutWidget_3)
self.btn_SetThreadNum.setObjectName("btn_SetThreadNum")
self.horizontalLayout_3.addWidget(self.btn_SetThreadNum)
self.horizontalLayoutWidget_5 = QtWidgets.QWidget(self.centralwidget)
self.horizontalLayoutWidget_5.setGeometry(QtCore.QRect(10, 560, 681, 41))
self.horizontalLayoutWidget_5.setObjectName("horizontalLayoutWidget_5")
self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget_5)
self.horizontalLayout_5.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem1)
self.btn_OneDownload = QtWidgets.QPushButton(self.horizontalLayoutWidget_5)
self.btn_OneDownload.setObjectName("btn_OneDownload")
self.horizontalLayout_5.addWidget(self.btn_OneDownload)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_5.addItem(spacerItem2)
self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 159, 681, 391))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidget = QtWidgets.QTableWidget(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.tableWidget.setFont(font)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
item.setFont(font)
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
item.setFont(font)
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
item.setFont(font)
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
item.setFont(font)
self.tableWidget.setHorizontalHeaderItem(3, item)
self.verticalLayout.addWidget(self.tableWidget)
self.label_4 = QtWidgets.QLabel(self.verticalLayoutWidget)
self.label_4.setObjectName("label_4")
self.verticalLayout.addWidget(self.label_4)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.signal_single_link.connect(self.showSingalInfo)
#绑定测试信号:
def showSingalInfo(self,file_name,file_size,file_progress):
self.label_txt_path.setText('文件名:'+file_name+'文件大小:'+file_size+'文件进度:'+file_progress)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "筑龙批量下载工具"))
self.label.setText(_translate("MainWindow", "请输入登录Cookies:"))
self.label_2.setText(_translate("MainWindow", "请输入单条链接:"))
self.btn_DownloadSingleLink.setText(_translate("MainWindow", "点击下载"))
self.label_3.setText(_translate("MainWindow", "请选择txt文件:"))
self.btn_OpenTxtPath.setText(_translate("MainWindow", "点击打开txt文件"))
self.label_txt_path.setText(_translate("MainWindow", "显示txt文件路径"))
self.btn_SetThreadNum.setText(_translate("MainWindow", "设置线程数"))
self.btn_OneDownload.setText(_translate("MainWindow", "一键下载"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "序号"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "文件名"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "文件大小"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("MainWindow", "当前进度"))
self.label_4.setText(_translate("MainWindow", " tips:登录Cookies为必填项,默认线程数为5"))
def DownloadSingleLink(self):
# brief:下载单条链接
self.cookie = self.lineEdit_Cookies.text().strip()
if self.cookie == '':
QMessageBox.warning(None,'下载单条链接','cookie为空,请输入cookie后再下载!')
return
if self.cookie != '':
cookie_str = convertCookie(self.cookie)
self.download_url = self.lineEdit_SingleLink.text().strip()
if self.download_url !='':
download_list = self.download_url.split('aid=')
download_name = download_list[len(download_list)-1]+'.pdf'
_thread.start_new_thread(self.downloadFile,(download_name,self.download_url,cookie_str))#Pdf下载
def downloadFile(self,name, url, login_cookie):
'''
:param name:下载保存的名称
:param url: 下载链接
:return:
'''
headers = {'Proxy-Connection': 'keep-alive'}
r = requests.get(url, stream=True, headers=headers, cookies=login_cookie)
length = float(r.headers['content-length'])
Download_size_M = length / 1048576
file_size = str(round(Download_size_M, 1)) + 'M'
f = open(name, 'wb')
count = 0
count_tmp = 0
time1 = time.time()
for chunk in r.iter_content(chunk_size=512):
if chunk:
f.write(chunk)
count += len(chunk)
if time.time() - time1 > 2:
p = count / length * 100
speed = (count - count_tmp) / 1024 / 1024 / 2
count_tmp = count
print(name + ': ' + formatFloat(p) + '%' + ' Speed: ' + formatFloat(speed) + 'M/S')
self.signal_single_link.emit(str(name),str(file_size),str(formatFloat(p)))
time1 = time.time()
f.close()
if __name__ == '__main__':
#加密程序:
res = requests.get('https://duhuifeng.github.io/')
if res.text.strip() == '1':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
else:
print('error!')
作用是下载过程中,传进度返回给主线程显示
一个知识点:在PyQt中UI线程只能在主线程中进行。
显而易见,明显传递消息成功!说明信号与槽建立成功,信号与槽的玩法还有很多,这里只是简单介绍这种而已