python - 结合 PYQT GUI 显着增加了循环时间
问题描述
我一直致力于转换一个程序,该程序将 CSV 文件作为建模应用程序的输入,该应用程序迭代了数千个时间步,并对每个时间步进行计算。在这种格式下,程序最多需要 1-2 分钟才能完成。在计算过程中,我使用了一个简单的 TKinter 进度条来指示模拟进度。
使用 PyQT5 完成 UI 后,计算时间显着减慢。现在计算需要 30 多分钟。
我尝试过的事情:
QT 线程:我将计算推送到单独的工作线程,如下所示:https ://realpython.com/python-pyqt-qthread/
class Simulator(QObject):
def __init__(self,inputs):
super(Simulator, self).__init__()
self.inputs = inputs
finished = pyqtSignal()
progress = pyqtSignal(int)
def run_task(self):
print(self.inputs)
simEVs(self.inputs)
self.finished.emit()
隐藏 QWidgets 和阻塞信号:对于另一个项目,我发现更新 QTable 小部件会由于发送大量信号而减慢程序速度,因此阻止小部件的信号提高了那里的性能。在这里,我尝试在模拟期间阻止信号并隐藏我的 UI 的所有子元素,但没有效果。
def sleep_ui(self):
children = self.findChildren(QWidget)
for child in children: #ignore the double indent here
child.blockSignals(True)
child.setUpdatesEnabled(False)
child.hide()
def wake_ui(self):
children = self.findChildren(QWidget)
for child in children:
child.blockSignals(True)
child.setUpdatesEnabled(True)
child.show()
在其他代码实现中,我删除了 ui 窗口并在计算完成后重新创建它,但我试图在这里避免这种情况。
这是我正在谈论的一个例子:
longsim() 使用 UI 需要 0.0029883 秒,不使用 UI 需要 0.0009970 秒,计算时间增加了近 300%。
longsim.py:
import pyqtgraph as pg
import numpy as np
import matplotlib
matplotlib.use('Qt5Agg')
import time
pg.mkQApp()
def longsim():
t = time.time()
# do stuff
tmax = 365*24*4
timev = np.linspace(0,tmax)
for i in timev:
for i in timev: # an example loop with some placeholder calculations
output = i*100
elapsed = time.time() - t
print(elapsed)
堆栈交换.py:
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import os
import matplotlib
from PyQt5 import QtWidgets, QtGui
from longloop import longsim
matplotlib.use('Qt5Agg')
pg.mkQApp()
path = os.path.dirname(os.path.abspath(__file__))
uiFile = os.path.join(path, 'Example.ui')
WindowTemplate, TemplateBaseClass = pg.Qt.loadUiType(uiFile)
class MainWindow(TemplateBaseClass):
def __init__(self):
TemplateBaseClass.__init__(self)
self.setWindowTitle('window')
# Create the main window
self.ui = WindowTemplate()
self.ui.setupUi(self)
self.ui.buttonBox.clicked.connect(self.clicked)
self.show()
def clicked(self):
longsim()
win = MainWindow()
if __name__ == '__main__':
import sys
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
这是 UI 文件:example.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>440</y>
<width>621</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
解决方案
谢谢大家的建议,通常情况下,像这样的错误在其他地方。在修复了一个应该是百分比的值(0-1 而不是 0-100)之后,循环将按应有的方式运行。到目前为止,还没有增加循环时间的问题。
推荐阅读
- python - spyder、jupyter 中的“内核死了,正在重新启动”,并且代码在 atom 中不起作用
- swift - 带有完成块的 Swift 异步
- html - 负边距增加了不需要的 1px 额外间距
- javascript - 在 jquery 中查找 nth-child 中的文本
- protractor - 量角器打字稿在非角度应用程序中关闭弹出窗口
- cookies - AspNetCore:OpenId Cookies 始终显示 expires=1969-12-31 即使设置了 IsPersistent=true 和 ExpireTimeSpan
- java - 由于 Apache Ignite 上的 JDBC 出现意外的运行时异常而无法执行作业
- database - SQL 数据库/列名约定 + 语言代码
- java - 尝试从String转换非常大的数字时如何解决Java中的NumberFormatException
- c# - 服务尚未启动