Python 使用pyqt的正确方法是什么?
下面的代码给出了一个错误消息: “QObject::startTimer:无法从其他线程启动计时器。” 我真的不明白为什么。主要是因为我几乎遇到了线程问题以及信号和插槽机制。如何将“int(percent)”变量传递到对话框或主GUI对话框,以获得progressbar对象的实时刷新Python 使用pyqt的正确方法是什么?,python,multithreading,pyqt,pyqt4,qprogressbar,Python,Multithreading,Pyqt,Pyqt4,Qprogressbar,下面的代码给出了一个错误消息: “QObject::startTimer:无法从其他线程启动计时器。” 我真的不明白为什么。主要是因为我几乎遇到了线程问题以及信号和插槽机制。如何将“int(percent)”变量传递到对话框或主GUI对话框,以获得progressbar对象的实时刷新 from PyQt4.QtCore import * from PyQt4.QtGui import * import sys import urllib.request class Main(QWidget):
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
import urllib.request
class Main(QWidget):
def __init__(self, parent = None):
super(Main, self).__init__()
self.label = QLabel("TheMainGUI")
self.pushbutton = QPushButton("Download")
layout = QHBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.pushbutton)
self.setLayout(layout)
self.pushbutton.clicked.connect(self.download)
def download(self):
self.filedownloadthread = FileDownloadThread()
self.filedownloadthread.start()
class Dialog(QDialog):
def __init__(self, parent = None):
super(Dialog, self).__init__()
self.progbar = QProgressBar()
layout = QVBoxLayout()
layout.addWidget(self.progbar)
self.setLayout(layout)
class FileDownloadThread(QThread):
def __init__(self):
super(FileDownloadThread, self).__init__()
self.dialog = Dialog()
self.dialog.show()
def run(self):
url = "http://mysource.net//myfile"
outputfile = "d://file//path//etc//myfile"
def reporthook(blocknum, blocksize, totalsize):
readsofar = blocknum * blocksize
if totalsize > 0:
percent = readsofar * 1e2 / totalsize
self.dialog.progbar.setValue(int(percent))
s = "\r%5.1f%% %*d / %d" % (
percent, len(str(totalsize)), readsofar, totalsize)
sys.stderr.write(s)
if readsofar >= totalsize:
sys.stderr.write("\n")
else:
sys.stderr.write("read %d\n" % (readsofar,))
proxy = urllib.request.ProxyHandler({'http': "myproxy"})
opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, outputfile, reporthook)
app = QApplication(sys.argv)
form = Main()
form.show()
app.exec_()
使用旧的信号和插槽机制,它可以正常工作
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
import urllib.request
class Main(QWidget):
def __init__(self, parent = None):
super(Main, self).__init__()
self.label = QLabel("TheMainGUI")
self.pushbutton = QPushButton("Download")
layout = QHBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.pushbutton)
self.setLayout(layout)
self.pushbutton.clicked.connect(self.download)
def download(self):
self.dialog = Dialog()
self.dialog.show()
class Dialog(QDialog):
def __init__(self, parent = None):
super(Dialog, self).__init__()
self.progbar = QProgressBar()
layout = QVBoxLayout()
layout.addWidget(self.progbar)
self.setLayout(layout)
self.filedownloadthread = FileDownloadThread()
self.connect(self.filedownloadthread, SIGNAL('signal'), self.update)
self.filedownloadthread.start()
def update(self, percent):
self.progbar.setValue(percent)
class FileDownloadThread(QThread):
def __init__(self):
super(FileDownloadThread, self).__init__()
def run(self):
url = "http://mysource.net//myfile"
outputfile = "d://file//path//etc//myfile"
def reporthook(blocknum, blocksize, totalsize):
readsofar = blocknum * blocksize
if totalsize > 0:
percent = readsofar * 1e2 / totalsize
self.dialog.progbar.setValue(int(percent))
s = "\r%5.1f%% %*d / %d" % (
percent, len(str(totalsize)), readsofar, totalsize)
sys.stderr.write(s)
if readsofar >= totalsize:
sys.stderr.write("\n")
else:
sys.stderr.write("read %d\n" % (readsofar,))
self.emit(SIGNAL('signal'), int(percent))
proxy = urllib.request.ProxyHandler({'http': "myproxy"})
opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)
urllib.request.urlretrieve(url, outputfile, reporthook)
app = QApplication(sys.argv)
form = Main()
form.show()
app.exec_()
您不能在主线程之外创建或操作GUI元素。您应该在
FileDownloadThread
外部实例化对话框
(例如Main
内部),并从FileDownloadThread
向其发送信号以更新进度条。我更新了代码。那么这是对的吗?你的想法似乎是对的。现在能用了吗?我不太熟悉您使用的老式信号和插槽机制,因此我无法评论它是否正确。另外,尽量不要修改你原来的帖子,因为更新会使代码与你原来的问题不一致,因为这只会让其他人感到困惑。最好在原始帖子的末尾添加更新。请看这篇文章:我建议您切换到PyQt的“新”样式的信号/插槽机制。@user3419537我建议您将您的评论移动到一个答案