hey i heard that there is something called qt signals you can use it to change the GUI out side the main thread coz when i try to change it i get an error that i cant change the gui out of the main thread but i need it to edit the progressbar value so if anyone had a way to do it plz tell me
Try something like this:
# -*- coding: utf-8 -*- from PyQt4 import QtGui, QtCore from main_window import Ui_MainWindow from outside import Outside class MyForm(QtGui.QMainWindow): def __init__(self, parent=None): super(MyForm, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) outside = Outside() self.connect(outside, QtCore.SIGNAL("progress(int, int)"), self.progress) def progress(self, value, max_value): self.ui.progressBar.setMinimum(0) self.ui.progressBar.setMaximum(max_value) self.ui.progressBar.setValue(value)
# -*- coding: utf-8 -*- from PyQt4 import QtCore class Outside(QtCore.QThread): def __init__(self, parent=None): super(Outside, self).__init__(parent) self.start() def run(self): self.emit(QtCore.SIGNAL("progress(int, int)"), i + 1, len(something_iterable)) def __del__(self): self.exiting = True self.wait()
why there is
i + 1, len(something_iterable)
in the line 12 in the out side module?
This code is a simulation (hint) that drives your progress bar for testing purposes..
You have to replace it with code you want to move the progress bar with.
Edited 4 Years Ago by vegaseat
Badly copied piece of code. It should be:
def run(self): for i, item in enumerate(something_iterable): self.emit(QtCore.SIGNAL("progress(int, int)"), i + 1, len(something_iterable))
yeah but am using python threading module not QtThread
#after importing all modules and set the GUi..... def progress(self,X): self.progress.setProperty("value",x) def main(self): print "value is 0" self.progress(0) print "now it is 100" self.progress(100) t=threading.Thread(target=main) t.start()
I propose to use the
threading.Thread in this case.
It's mostly the same. The main difference is that QThreads are better integrated with Qt (asynchrnous signals/slots, event loop, etc.). Also, you can't use Qt from a Python thread (you can't for instance post event to the main thread through QApplication.postEvent): you need a QThread for that to work.
A general rule of thumb might be to use QThreads if you're going to interact somehow with Qt, and use Python threads otherwise.
Edited 4 Years Ago by nabla2
hmmm so it is a deadend....
is there a way to syc a var between a thread and the main GUI thread?
and what about pywx,pygtk,pytk?? can't i change the gui from a thread?
Of course, you can. Read this example carefully. You need a class that inherits from
QThread and implements the
run method, which is triggered by
start(). For communication between the thread and the GUI use the signals and slots.
At first it may be complicated. Writing multithreaded programs requires a bit more knowledge, regardless of whether you are using PyGTK, wxPython, etc.
PyQt is probably the best choice (in my opinion). Slightly modified example (with snippet for more pythonic API 2):
import sys import math import random import sip API_NAMES = ["QDate", "QDateTime", "QString","QTextStream", "QTime", "QUrl", "QVariant"] API_VERSION = 2 for name in API_NAMES: sip.setapi(name, API_VERSION) from PyQt4.QtCore import * from PyQt4.QtGui import * class Window(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.thread = Worker() label = QLabel("Number of stars:") self.spinBox = QSpinBox() self.spinBox.setMaximum(10000) self.spinBox.setValue(100) self.startButton = QPushButton("&Start") self.viewer = QLabel() self.viewer.setFixedSize(300, 300) self.connect(self.thread, SIGNAL("finished()"), self.updateUi) self.connect(self.thread, SIGNAL("terminated()"), self.updateUi) self.connect(self.thread, SIGNAL("output(QRect, QImage)"), self.addImage) self.connect(self.startButton, SIGNAL("clicked()"), self.makePicture) layout = QGridLayout() layout.addWidget(label, 0, 0) layout.addWidget(self.spinBox, 0, 1) layout.addWidget(self.startButton, 0, 2) layout.addWidget(self.viewer, 1, 0, 1, 3) self.setLayout(layout) self.setWindowTitle("Simple Threading Example") def makePicture(self): self.spinBox.setReadOnly(True) self.startButton.setEnabled(False) pixmap = QPixmap(self.viewer.size()) pixmap.fill(Qt.black) self.viewer.setPixmap(pixmap) self.thread.render(self.viewer.size(), self.spinBox.value()) def addImage(self, rect, image): pixmap = self.viewer.pixmap() painter = QPainter() painter.begin(pixmap) painter.drawImage(rect, image) painter.end() self.viewer.update(rect) def updateUi(self): self.spinBox.setReadOnly(False) self.startButton.setEnabled(True) class Worker(QThread): def __init__(self, parent=None): QThread.__init__(self, parent) self.exiting = False self.size = QSize(0, 0) self.stars = 0 self.path = QPainterPath() angle = 2*math.pi/5 self.outerRadius = 20 self.innerRadius = 8 self.path.moveTo(self.outerRadius, 0) for step in range(1, 6): self.path.lineTo( self.innerRadius * math.cos((step - 0.5) * angle), self.innerRadius * math.sin((step - 0.5) * angle) ) self.path.lineTo( self.outerRadius * math.cos(step * angle), self.outerRadius * math.sin(step * angle) ) self.path.closeSubpath() def __del__(self): self.exiting = True self.wait() def render(self, size, stars): self.size = size self.stars = stars self.start() def run(self): # Note: This is never called directly. It is called by Qt once the # thread environment has been set up. random.seed() n = self.stars width = self.size.width() height = self.size.height() while not self.exiting and n > 0: image = QImage(self.outerRadius * 2, self.outerRadius * 2, QImage.Format_ARGB32) image.fill(qRgba(0, 0, 0, 0)) x = random.randrange(0, width) y = random.randrange(0, height) angle = random.randrange(0, 360) red = random.randrange(0, 256) green = random.randrange(0, 256) blue = random.randrange(0, 256) alpha = random.randrange(0, 256) painter = QPainter() painter.begin(image) painter.setRenderHint(QPainter.Antialiasing) painter.setPen(Qt.NoPen) painter.setBrush(QColor(red, green, blue, alpha)) painter.translate(self.outerRadius, self.outerRadius) painter.rotate(angle) painter.drawPath(self.path) painter.end() self.emit(SIGNAL("output(QRect, QImage)"), QRect(x - self.outerRadius, y - self.outerRadius, self.outerRadius * 2, self.outerRadius * 2), image) n -= 1 if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() app.exec_()
Edited 4 Years Ago by nabla2
hmmmm i guess i need a good tutorial for Qt anyway thanx this question should be marked as solved :)
Hi, as I was told that my code doesn’t scale well at all, I thought perhaps I’d try to get a better understanding of interfaces/abstract classes and classes and the relationship between them.
I don’t want at this stage work on a big separate project as I've already got plenty ...
Hey, so I wanna ask how I need to create a method who will remove word if in that word is 2 same chars. Example: "Potato" in this word there is a 2 "o" chars so this word will need to be removed. "Forum" in this word there is no ...
Hi I'm having a problem implementing a mini shopping cart drop down in the header to show the user all the products they have in their shopping cart. It seems the only solution for this is Ajax, and I've looked all over and can't find anything that I could possibly ...