python 2.7 / Pyside (如果使用pyQt4,将Pyside直接替换PyQt4即可)
首先我们在Qt Designer中画好界面并自动生成design.py,注意生成后还要部分收到修改,然后创建main.py
design.py 主要负责写软件界面的文件。
main.py 主要负责写业务逻辑的文件。
design.py
# -*- coding: utf-8 -*-
from PySide import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(526, 373)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.subreddits_input_layout = QtGui.QHBoxLayout()
self.subreddits_input_layout.setObjectName(_fromUtf8("subreddits_input_layout"))
self.label_subreddits = QtGui.QLabel(self.centralwidget)
self.label_subreddits.setObjectName(_fromUtf8("label_subreddits"))
self.subreddits_input_layout.addWidget(self.label_subreddits)
self.edit_subreddits = QtGui.QLineEdit(self.centralwidget)
self.edit_subreddits.setObjectName(_fromUtf8("edit_subreddits"))
self.subreddits_input_layout.addWidget(self.edit_subreddits)
self.verticalLayout.addLayout(self.subreddits_input_layout)
self.label_submissions_list = QtGui.QLabel(self.centralwidget)
self.label_submissions_list.setObjectName(_fromUtf8("label_submissions_list"))
self.verticalLayout.addWidget(self.label_submissions_list)
self.list_submissions = QtGui.QListWidget(self.centralwidget)
self.list_submissions.setBatchSize(1)
self.list_submissions.setObjectName(_fromUtf8("list_submissions"))
self.verticalLayout.addWidget(self.list_submissions)
self.progress_bar = QtGui.QProgressBar(self.centralwidget)
self.progress_bar.setProperty("value", 0)
self.progress_bar.setObjectName(_fromUtf8("progress_bar"))
self.verticalLayout.addWidget(self.progress_bar)
self.buttons_layout = QtGui.QHBoxLayout()
self.buttons_layout.setObjectName(_fromUtf8("buttons_layout"))
self.btn_stop = QtGui.QPushButton(self.centralwidget)
self.btn_stop.setEnabled(False)
self.btn_stop.setObjectName(_fromUtf8("btn_stop"))
self.buttons_layout.addWidget(self.btn_stop)
self.btn_start = QtGui.QPushButton(self.centralwidget)
self.btn_start.setObjectName(_fromUtf8("btn_start"))
self.buttons_layout.addWidget(self.btn_start)
self.verticalLayout.addLayout(self.buttons_layout)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "Threading Tutorial - nikolak.com", None))
self.label_subreddits.setText(_translate("MainWindow", "Subreddits:", None))
self.edit_subreddits.setPlaceholderText(_translate("MainWindow", "python,programming,linux,etc (comma separated)", None))
self.label_submissions_list.setText(_translate("MainWindow", "Submissions:", None))
self.btn_stop.setText(_translate("MainWindow", "Stop", None))
self.btn_start.setText(_translate("MainWindow", "Start", None))
main.py
# -*- coding: utf-8 -*-
from PySide import QtGui
from PySide.QtCore import QThread, SIGNAL
import sys
import design
import urllib2
import json
import time
class getPostsThread(QThread):
'''线程类'''
def __init__(self, subreddits):
QThread.__init__(self)
self.subreddits = subreddits
def __del__(self):
self.wait()
def _get_top_post(self, subreddit):
"""从唯一必需参数传递的subreddit返回带有顶部帖子标题,作者和subreddit名称的预格式化字符串。"""
url = "https://www.reddit.com/r/{}.json?limit=1".format(subreddit)
headers = {'User-Agent': '[email protected] tutorial code'}
request = urllib2.Request(url, headers=headers)
response = urllib2.urlopen(request)
data = json.load(response)
top_post = data['data']['children'][0]['data']
return "'{title}' by {author} in {subreddit}".format(**top_post)
def run(self):
"""用start()运行"""
# 遍历self.subreddits列表中的每个项目(在__init__期间提供),并且对于每个项目,
for subreddit in self.subreddits:
# 获取有效subreddit名称的字符串,并使用reddit中的_get_top_post方法获取顶部帖子。将结果存储在名为top_post的局部变量中。
top_post = self._get_top_post(subreddit)
# 然后发出'SIGNAL add_post(QString)'信号,其中QString等于_get_top_post函数设置的top_post变量。
self.emit(SIGNAL('add_post(QString)'), top_post)
self.sleep(2)
class ThreadingTutorial(QtGui.QMainWindow, design.Ui_MainWindow):
"""主逻辑类,需要继承UI类"""
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
# 将“启动”按钮链接到start_getting_top_posts函数中
self.btn_start.clicked.connect(self.start_getting_top_posts)
def start_getting_top_posts(self):
# 获取信息
# 获取s用户输入到QLineEdit字段中
subreddit_list = str(self.edit_subreddits.text()).split(',')
# 如果没有输入文字,这将等于''
if subreddit_list == ['']:
# 是否有任何东西可以从中获取,如果没有显示消息并中止
QtGui.QMessageBox.critical(self, "No subreddits","You didn't enter any subreddits.",QtGui.QMessageBox.Ok)
return
# 初始化值
# 设置进度条的最大值,可以是任意int,它将自动转换为x/100%值
# 例如max_value = 3,current_value = 1,进度条将显示33%
self.progress_bar.setMaximum(len(subreddit_list))
# 将每次运行的值初始化设置为0
self.progress_bar.setValue(0)
# 创建线程
# 我们创建一个新的getPostsThread线程实例,将subreddits列表传递给线程
self.get_thread = getPostsThread(subreddit_list)
# 连接
# 接下来,我们将来自getPostsThread线程的事件连接到我们希望在这些信号被触发时运行的函数,这里介绍两种信号处理
# 连接自定义信号
# 添加返回信息将在本类的add_post方法中进行处理,并且线程将发出的信号是‘SIGNAL(“add_post(QString)”)’,
# 其余我们可以用相同的方法来连接任何信号
self.get_thread.connect(SIGNAL("add_post(QString)"), self.add_post)
# 连接内置信号
# 无论线程是完成还是终止,我们希望向用户显示已完成的通知,无论是主动终止还是已完成
# 完成的信号将熄灭。所以我们不需要专门捕捉已终止,但如果我们想要的话,也可以去做。
self.get_thread.connect(SIGNAL("finished()"), self.done)
# 启动线程的事件
self.get_thread.start()
# 当线程开始运行时,能允许用户停止/终止线程,所以我们启用“停止”按钮
self.btn_stop.setEnabled(True)
# 我们将“停止”按钮的单击连接到QThread实例所具有的内置终止方法terminate/quit
#self.btn_stop.clicked.connect(self.get_thread.terminate)
self.btn_stop.clicked.connect(self.get_thread.quit)
# 我们不希望用户在此线程运行时启动另一个线程,因此我们禁用了“启动”按钮。
self.btn_start.setEnabled(False)
def add_post(self, post_text):
"""将给定此函数的文本添加到我们GUI中的list_submissions QListWidget中,并将进度条的当前值增加1"""
self.list_submissions.addItem(post_text)
self.progress_bar.setValue(self.progress_bar.value() + 1)
def done(self):
# 禁用“停止”按钮,
self.btn_stop.setEnabled(False)
# 启用“启动”按钮
self.btn_start.setEnabled(True)
# 将进度条重置为0
self.progress_bar.setValue(0)
# 弹出提示信息
QtGui.QMessageBox.information(self, "Done!", "Done fetching posts!")
def main():
# 创建应用
app = QtGui.QApplication(sys.argv)
# 创建实例表单
form = ThreadingTutorial()
# 显示实例
form.show()
# 退出程序
app.exec_()
if __name__ == '__main__':
main()
https://nikolak.com/pyqt-threading-tutorial/