Python: скрипт не запускается без печати

#python-2.7 #qt4 #pyqt4

#python-2.7 #qt4 #pyqt4

Вопрос:

Я написал небольшой исполняемый скрипт. Эта программа работает только тогда, когда я использую print -оператор (в конце on_start() -метода QDialog() класса). Пожалуйста, взгляните на on_start() -метод QDialog -класса.

Как вы можете видеть, я создаю a task_thread — и work_object -экземпляр. Но, когда я выполняю этот скрипт без print -statement, ничего не происходит — нет трассировки или других сообщений об ошибках.

Где ошибка? Я предполагаю, что проблема в том, что я создаю экземпляры на локальном уровне — я не уверен. Как я могу это исправить?

 import sys
from time import sleep

from PyQt4.QtCore import QThread, pyqtSignal, Qt, QStringList, QObject, QTimer
from PyQt4.QtGui import QVBoxLayout, QPushButton, QDialog, QProgressBar, QApplication, 
     QMessageBox, QTreeWidget, QTreeWidgetItem, QLabel

def create_items(total):
     for elem in range(total):
         yield elem

class WorkObject(QObject):

    notify_progress = pyqtSignal(object)
    fire_label = pyqtSignal(object)
    finished = pyqtSignal()

    def __init__(self, parent=None):
        QObject.__init__(self, parent)

    def add_items(self):
         total = 190000

         x = (total/100*1)
         a = x

         counter = 0

         for element in create_items(10000):
              counter  = 1
              self.notify_progress.emit((element))
              self.fire_label.emit((counter))

              if counter == x:
                   x  = a
                   sleep(1)

              if not self.keep_running:
                   self.keep_running = True
                   break

    def run(self):
         self.keep_running = True
         self.add_items()

    def stop(self):
         self.keep_running = False


class MyCustomDialog(QDialog):

    finish = pyqtSignal()

    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        layout = QVBoxLayout(self)

        self.tree = QTreeWidget(self)
        self.label = QLabel(self)

        self.pushButton_start = QPushButton("Start", self)
        self.pushButton_stopp = QPushButton("Stopp", self)
        self.pushButton_close = QPushButton("Close", self)

        layout.addWidget(self.label)
        layout.addWidget(self.tree)
        layout.addWidget(self.pushButton_start)
        layout.addWidget(self.pushButton_stopp)
        layout.addWidget(self.pushButton_close)

        self.pushButton_start.clicked.connect(self.on_start)
        self.pushButton_stopp.clicked.connect(self.on_finish)
        self.pushButton_close.clicked.connect(self.close)

    def fill_tree_widget(self, i):
        parent = QTreeWidgetItem(self.tree)
        self.tree.addTopLevelItem(parent)
        parent.setText(0, unicode(i))
        parent.setCheckState(0, Qt.Unchecked)
        parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)

    def on_label(self, i):
         self.label.setText("Result: {}".format(i))

    def on_start(self):
         self.tree.clear()
         self.label.clear()

         task_thread = QThread(self)
         work_object = WorkObject()

         work_object.fire_label.connect(self.on_label)
         work_object.notify_progress.connect(self.fill_tree_widget)
         work_object.finished.connect(task_thread.quit)

         self.finish.connect(work_object.stop)

         work_object.moveToThread(task_thread)

         task_thread.started.connect(work_object.run)

         task_thread.finished.connect(task_thread.deleteLater)

         timer = QTimer()

         # I set the single shot timer on False,
         # because I don't want the timer to fires only once,
         # it should fires every interval milliseconds
         timer.setSingleShot(False)
         timer.timeout.connect(work_object.stop)
         timer.start(0)

         task_thread.start()

         print

    def on_finish(self):
         self.finish.emit()

def main():
    app = QApplication(sys.argv)
    window = MyCustomDialog()
    window.resize(600, 400)
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()
 

Ответ №1:

Вы правы, work_object создается как локальный экземпляр.

Вот простое решение:

 work_object = WorkObject()
self.work_object = work_object  # Add this line