2011-11-04 14 views
5

यह प्रश्न कई अलग-अलग रूपों में कई बार पूछा गया है लेकिन मैंने इसे एक के साथ प्रासंगिक नहीं पाया है मेरा कोड-समाधान।लूपिंग QProgressBar त्रुटि देता है >> QObject :: installEventFilter: किसी भिन्न थ्रेड में ऑब्जेक्ट्स के लिए ईवेंट फ़िल्टर नहीं कर सकता

जब मैं कार्यक्रम चलाने यह पता चलता है

QObject :: installEventFilter: एक अलग धागे में वस्तुओं के लिए घटनाओं फ़िल्टर नहीं कर सकते।

इसके बावजूद कोड प्रारंभ में काम करता है लेकिन थोड़ी देर बाद यह बम और पायथन एक त्रुटि देता है जिसमें यह काम करना बंद कर देता है।

मेरे कोड इस प्रकार है:

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
from xml.etree import ElementTree as ET 
import os , time 

class LayoutCreator(QDialog): 
    def __init__(self , parent=None): 
     super(LayoutCreator, self).__init__(parent) 
     self.Cameras_Update() 


    def Cameras_Update(self):            # Get all shots with camera plots and add them to the cameras_tree 
     busyBar = sqrl_QtTools.BusyBar(text = "Gathering Camera Data") # Looping progress bar 
     busyBar.start() 

     # loop through folder structure storing data     

     busyBar.Kill()              # Close looping progress bar  


class BusyBar(QThread):      # Looping progress bar 
    def __init__(self, text = ""): 
     QThread.__init__(self) 
     self.text = text 
     self.stop = False 

    def run(self): 
     self.proBar = QProgressBar() 
     self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) 
     self.proBar.setMinimum(0) 
     self.proBar.setMaximum(100) 
     self.proBar.setTextVisible(True) 
     self.proBar.setFormat(self.text) 
     self.proBar.setValue(0) 
     self.proBar.setFixedSize(500 , 50) 
     self.proBar.setAlignment(Qt.AlignCenter) 
     self.proBar.show() 
     while not self.stop:    # keep looping while self is visible 
      # Loop sending mail 
      for i in range(100): 
       progress = self.proBar.value() 
       progress = progress + 1 
       self.proBar.setValue(progress) 

       time.sleep(0.05) 
      self.proBar.setValue(0) 
     self.proBar.hide() 

    def Kill(self): 
     self.stop = True 

उत्तर

6

आप नहीं बना सकते या मुख्य थ्रेड से बाहर किसी भी QWidget पहुँच सकते हैं।

आप संकेतों और स्लॉट का उपयोग कर सकते परोक्ष रूप से अन्य धागे से विजेट का उपयोग करने की:

from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
import sys, time 

class BusyBar(QThread):      # Looping progress bar 
    # create the signal that the thread will emit 
    changeValue = pyqtSignal(int) 
    def __init__(self, text = ""): 
     QThread.__init__(self) 
     self.text = text 
     self.stop = False 
     self.proBar = QProgressBar() 
     self.proBar.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.SplashScreen) 
     self.proBar.setRange(0, 100) 
     self.proBar.setTextVisible(True) 
     self.proBar.setFormat(self.text) 
     self.proBar.setValue(0) 
     self.proBar.setFixedSize(500 , 50) 
     self.proBar.setAlignment(Qt.AlignCenter) 
     self.proBar.show() 

     self.changeValue.connect(self.proBar.setValue, Qt.QueuedConnection) 
     # Make the Busybar delete itself and the QProgressBar when done   
     self.finished.connect(self.onFinished) 

    def run(self): 
     while not self.stop:    # keep looping while self is visible 
      # Loop sending mail 
      for i in range(100): 
       # emit the signal instead of calling setValue 
       # also we can't read the progress bar value from the thread 
       self.changeValue.emit(i) 
       time.sleep(0.05) 
      self.changeValue.emit(0) 

    def onFinished(self): 
     self.proBar.deleteLater() 
     self.deleteLater() 

    def Kill(self): 
     self.stop = True 

class LayoutCreator(QDialog): 
    def __init__(self , parent=None): 
     super(LayoutCreator, self).__init__(parent) 
     self.Cameras_Update() 

    def Cameras_Update(self):          
     # Looping progress bar 
     self.busyBar = BusyBar(text = "Gathering Camera Data") 
     self.busyBar.start() 

     # loop through folder structure storing data 

     # Simulate async activity that doesn't block the GUI event loop 
     # (if you do everything without giving control back to 
     # the event loop, you have to call QApplication.processEvents() 
     # to allow the GUI to update itself) 
     QTimer.singleShot(10000, self.stopBar) 

    def stopBar(self): 
     self.busyBar.Kill()      # Close looping progress bar  

app = QApplication(sys.argv) 
win = LayoutCreator() 
win.show(); 
sys.exit(app.exec_()) 

या

आप केवल एक व्यस्त सूचक चाहते हैं, तो आप बस दोनों न्यूनतम सेट कर सकते हैं और अधिकतम QProgressBar से 0 तक, और आपको दस्तावेज़ में इंगित किए गए थ्रेड की आवश्यकता नहीं होगी।

+0

धन्यवाद लेकिन मुझे काम करने के लिए आपका उदाहरण नहीं मिल रहा है। क्या आप मुझे उस कोड का उदाहरण दे सकते हैं जिसका उपयोग आप इसे निष्पादित करने के लिए करते हैं क्योंकि मुझे अभी भी त्रुटियां मिल रही हैं? – Jared

+0

@mushu मैंने बाकी कोड को जोड़ा जो मैंने उपयोग किया था। – alexisdm

+0

बहुत बढ़िया। एक आकर्षण की तरह काम करता है, धन्यवाद – Jared