我在Python3.5中遇到了一个奇怪的问题。
我有两个类,FrontEnd(QWidget)
和{FrontEnd
的init函数中定义了许多QLabel
,所有这些都能正常工作。在
显示了FrontEnd
的相关函数:
def update_ui(self):
ret, frame = self.cam_capture.read()
if self.results_pending:
if not path.isfile('output.jpg'):
self.results_pending = False
with open('.out') as content_file:
content = content_file.readlines()[2:-2]
system('rm .out')
self.handle_image_classification(content)
if self.take_picture:
cv2.imwrite('output.jpg', frame)
self.user_prompt.setText('Please wait...')
system('./classifyimage.py --mean mean.binaryproto --nogpu --labels labels.txt model.caffemodel deploy.prototxt output.jpg > .out && rm output.jpg')
self.take_picture = False
self.results_pending = True
image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888).rgbSwapped()
pix = QPixmap.fromImage(image)
self.video_frame.setPixmap(pix)
def update_bar_graph(self, data):
palette = QPalette()
palette.setColor(QPalette.Background, Qt.white)
for i in range(0, 8):
self.bar_graph_labels[i].setText(str(data[i]) + "%")
height = int(data[i] * 5)
self.bar_graph[i].setFixedSize(self.bar_width, height)
self.bar_graph[i].move(1280 + (i * (self.bar_width + self.bar_spacing)), 640 - height)
def handle_image_classification(self, raw_output):
data = [None] * 8
for i in range(0, len(raw_output)):
raw_output[i] = raw_output[i].strip()
data[int(raw_output[i][-2]) - 1] = float(raw_output[i][:-10])
self.update_bar_graph(data)
整个时间阅读课:
^{pr2}$(TimerThread
的front_end
元素设置在FrontEnd
的init上)
问题出在update_bar_graph
函数中。当setFixedSize
调用被注释掉时,程序运行良好,尽管在我的应用程序中没有正确显示条形图的条形图(它们是QLabels
)。move
函数似乎运行正常。但是,setFixedSize
调用会导致此错误:
QObject::startTimer: Timers cannot be started from another thread
QObject::startTimer: Timers cannot be started from another thread
QObject::killTimer: Timers cannot be stopped from another thread
QObject::startTimer: Timers cannot be started from another thread
我完全不知道为什么会发生这种情况,也不知道为什么move
函数在本质上看起来很相似,但却工作得很好。任何帮助都将不胜感激。
(如果我应该使用不同类型的计时器类或在PyQt中绘制大矩形的不同方法,我愿意接受任何此类建议)。在
编辑:
这是一些奇怪的东西。第二天我运行了两次,代码没有改变。(我想…)有一次条形图没有显示,但是没有抛出错误。另一次我得到这个:
7fdfaf931000-7fdfaf932000 r--p 0007a000 08:07 655633 /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5.5.1
7fdfaf932000-7fdfaf933000 rw-p 0007b000 08:07 655633 /usr/lib/x86_64-linux-gnu/libQt5DBus.so.5.5.1
7fdfaf933000-7fdfaf934000 rw-p 00000000 00:00 0
7fdfaf934000-7fdfaf971000 r-xp 00000000 08:07 667112 /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0.0.0
7fdfaf971000-7fdfafb70000 ---p 0003d000 08:07 667112 /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0.0.0
7fdfafb70000-7fdfafb72000 r--p 0003c000 08:07 667112 /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0.0.0
7fdfafb72000-7fdfafb73000 rw-p 0003e000 08:07 667112 /usr/lib/x86_64-linux-gnu/libxkbcommon.so.0.0.0
7fdfafb73000-7fdfafb7a000 r-xp 00000000 08:07 667110 /usr/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0.0.0
7fdfafb7a000-7fdfafd79000 ---p 00007000 08:07 667110 /usr/lib/x86_64-linux-gnu/libxkbcommon-x11.so.0.0.0
我想我可能在PyQt5发现了一个虫子。在
如@mata所述,您的代码不是线程安全的。这很可能是错误行为的来源,在进一步调试之前,应该确定地进行修复(与this相关)。在
线程不安全的原因是因为您直接从辅助线程与GUI对象交互。你应该从你的线程发出一个信号到主线程中的一个插槽,在那里你可以安全地更新你的GUI。{{a3}无论如何,这是推荐使用的。在
这需要进行以下更改:
我还修改了您的代码,以便它在
FrontEnd
对象中存储对TimerThread
的引用,这样线程就不会被垃圾回收了。在我还要补充一点,这是一种过于复杂的每0.02秒触发一次更新的方法。您可以使用
QTimer
来调用update_ui
方法并完全丢弃线程,但我采用的方法是,您可能希望以后对线程执行更复杂的操作,因此我们演示了如何安全地执行该操作!在相关问题 更多 >
编程相关推荐