我正在用gphoto2拍照,我想把它们异步地放到一个列表小部件上,因为某些原因,它没有按预期工作。它在一个QThread上获取照片,但是在所有照片都被拍摄完成之前,它不会将照片添加到列表中(就像批量添加)。我该怎么做?在
以下是相关的源代码(它不会编译,因为有太多的依赖项无法满足问题):
class DownloadThread(QThread):
data_downloaded = Signal(object)
def __init__(self, photo_name):
QThread.__init__(self)
self.photo_name = photo_name
def run(self):
image_location = capture_image.take_photo(self.photo_name)
image = QImage(image_location)
to_pixmap = QPixmap.fromImage(image).scaled(200, 200)
to_qicon = QIcon(to_pixmap)
self.data_downloaded.emit(QListWidgetItem(to_qicon, image_location))
class MainWindow(QMainWindow, Ui_MainWindow):
def take_photo(self):
import time
for x in range(2):
photo_name = str(x) +'.jpg'
downloader = DownloadThread(photo_name)
downloader.data_downloaded.connect(self.on_photo_ready)
downloader.start()
time.sleep(5)
def on_photo_ready(self, photo):
print "WHY"
self.listWidget.addItem(photo)
我在被调用的函数中有一些简单的print语句,因此终端如下所示:
照片 照片 照片 照片 照片 照片 为什么? 为什么? 为什么? 为什么? 为什么? 为什么
这意味着它等待实际调用emit,直到for循环完成,而不是按预期在它自己的线程上。任何帮助都会很棒!在
告诉主线程在次线程工作时休眠。这将把你所有的信号排成一列,这样它们就能立刻到达。删除
time.sleep(5)
并更改到
^{pr2}$你应该没事的。在
也就是说,工人模型是件好事。有关详细信息,请参见this question或this one。在
有几个问题
1。你的线程实际上没有运行
您需要调用
QThread.start()
来实际运行QThread.run()
。也就是说,你可能不想这样设计你的应用程序。没有理由为每个图片下载创建几十个或数百个不同的线程。如果创建一个工作线程来下载队列中的所有映像,效率会高得多。示例见下文。在2。不能在辅助线程
中创建qpixmap或GUI项不能在主线程之外创建
QPixmap
。您既不能创建QListWidgetItem
,也不能创建任何GUI元素;它们只能在主线程中创建(并安全地操作)。您可以使用其他类似的元素(比如QImage
),但实际上,您只需要将下载的文件路径传递回主线程;主线程可以处理QPixmap
和项创建。在相关问题 更多 >
编程相关推荐