MainWindow 不会同时处理事件和用户操作
MainWindow do not process events and user actions concurrently
我有一个使用 Qt Designer 制作的 PyQt5 MainWindow。
此 window 应该抓取网站并在找到后在 TreeView 中列出已抓取的 link。
我可以通过创建模型来做到这一点,QStandardItemModel
每次抓取新的 link 时,将所有 link 添加到模型中,然后将模型设置为TreeView.setModel(model)
的树,然后我调用 QtWidgets.qApp.processEvents()
所以 window 被更新。当软件抓取站点时,window 不会响应用户交互,直到执行 QtWidgets.qApp.processEvents()
。
如何使用最新抓取的 link 更新我的 TreeView 并且在抓取过程中仍然让我的 window 难以处理?
这是我的代码
def start(self):
## start crawling
self.populate_tree(crawled_links)
def populate_tree(self, links):
data = []
for index in links:
item = (links[index]['from'], [])
for link in links[index]['url']:
item[1].append((link, []))
data.append(item)
model = QtGui.QStandardItemModel()
self.__add_items(model, data)
self.treeView.setModel(model)
self.treeView.expandAll()
self.treeView.scrollToBottom()
self.treeView.setHeaderHidden(True)
QtWidgets.qApp.processEvents()
def __add_items(self, model, data):
for text, children in data:
item = QtGui.QStandardItem(text)
model.appendRow(item)
if children:
self.__add_items(item, children)
如果有任何帮助,crawled_links
列表如下所示:
crawled_links = {
0:{
'url': {
'one.html',
'three.html'
},
'from':
'site1.com'
},
1:{
'url': {
'two.html'
},
'from':
'site1.com'
}
}
使用 processEvents()
是一种不好的做法,它们应该只用于某些特殊任务,如您所见并不能解决问题。
解决方案是在线程上执行任务,通过信号发送给GUI的线程。
import threading
from PyQt5 import QtCore, QtWidgets
class Helper(QtCore.QObject):
resultChanged = QtCore.pyqtSignal(dict)
def start_crawling(self):
crawled_links = {}
# processing
self.resultChanged.emit(crawled_links)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None)
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.helper = Helper()
self.helper.resultChanged.connect(self.populate_tree)
def start(self):
# start crawling
threading.Thread(target=self.helper.start_crawling, daemon=True).start()
def populate_tree(self, crawled_links)
...
我有一个使用 Qt Designer 制作的 PyQt5 MainWindow。
此 window 应该抓取网站并在找到后在 TreeView 中列出已抓取的 link。
我可以通过创建模型来做到这一点,QStandardItemModel
每次抓取新的 link 时,将所有 link 添加到模型中,然后将模型设置为TreeView.setModel(model)
的树,然后我调用 QtWidgets.qApp.processEvents()
所以 window 被更新。当软件抓取站点时,window 不会响应用户交互,直到执行 QtWidgets.qApp.processEvents()
。
如何使用最新抓取的 link 更新我的 TreeView 并且在抓取过程中仍然让我的 window 难以处理?
这是我的代码
def start(self):
## start crawling
self.populate_tree(crawled_links)
def populate_tree(self, links):
data = []
for index in links:
item = (links[index]['from'], [])
for link in links[index]['url']:
item[1].append((link, []))
data.append(item)
model = QtGui.QStandardItemModel()
self.__add_items(model, data)
self.treeView.setModel(model)
self.treeView.expandAll()
self.treeView.scrollToBottom()
self.treeView.setHeaderHidden(True)
QtWidgets.qApp.processEvents()
def __add_items(self, model, data):
for text, children in data:
item = QtGui.QStandardItem(text)
model.appendRow(item)
if children:
self.__add_items(item, children)
如果有任何帮助,crawled_links
列表如下所示:
crawled_links = {
0:{
'url': {
'one.html',
'three.html'
},
'from':
'site1.com'
},
1:{
'url': {
'two.html'
},
'from':
'site1.com'
}
}
使用 processEvents()
是一种不好的做法,它们应该只用于某些特殊任务,如您所见并不能解决问题。
解决方案是在线程上执行任务,通过信号发送给GUI的线程。
import threading
from PyQt5 import QtCore, QtWidgets
class Helper(QtCore.QObject):
resultChanged = QtCore.pyqtSignal(dict)
def start_crawling(self):
crawled_links = {}
# processing
self.resultChanged.emit(crawled_links)
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None)
QtWidgets.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.helper = Helper()
self.helper.resultChanged.connect(self.populate_tree)
def start(self):
# start crawling
threading.Thread(target=self.helper.start_crawling, daemon=True).start()
def populate_tree(self, crawled_links)
...