QThread/信号逻辑

1 投票
1 回答
1277 浏览
提问于 2025-04-16 20:13

我正在尝试为一个论坛写一个通知器。我想用一个QThread和QTimer定期检查是否有新回复。但是,我的线程中的check()函数并没有在线程里运行,而是阻塞了图形界面(GUI)。你能告诉我哪里出错了吗?

我怀疑是信号的问题,我使用QTimer的超时信号来运行check方法,但创建和连接超时信号到check函数的代码是在run方法之外的。但是当我把self.timer=QTimer(); timer.timeout.connect(self.check)放到run方法里面时,self.check从来没有被触发。无论如何,你能告诉我我哪里错了吗?

class Worker(QtCore.QThread):
    check_started = QtCore.pyqtSignal()
    check_successful = QtCore.pyqtSignal()
    check_failed = QtCore.pyqtSignal()

    def __init__(self, user="", password="", check_frequency=5):
        QtCore.QThread.__init__(self)
        self.login_info = {"user": user, "password": password}
        self.check_frequency = check_frequency
        self.last_check_time = 0

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.check) #Would it run in thread or not?

        self.unreads = {}

    def run(self):
        #When I do timer initialization here, it never triggers
        self.check()
        self.timer.start(self.check_frequency * 1000 * 60)

    def check(self):
        print "checking"
        self.last_check_time = time.time()
        self.check_started.emit()
        check_result = self.check_for_unreads()
        if check_result:
            self.check_successful.emit()
        else:
            self.check_failed.emit()

    def check_for_unreads(self):
        frm = Forum(self.login_info["user"], self.login_info["password"])
              #This class just uses Mechanize to fetch some pages;
              #Not calculation or CPU-intensive actions.
        if frm.login(): #returns true if successful login, else false
            frm.get_unread_replies()
            self.unreads=frm.unreads
            return True
        else:
            return False

抱歉问了这么多问题。如果有什么不清楚的地方,我会尽量解释得更详细。

编辑:这是我在图形界面代码中启动线程的方式:

self.checker = Worker()

self.checker.login_info["user"] = self.settings["user"]
self.checker.login_info["password"] = self.settings["password"]
self.checker.check_frequency = self.settings["time"]

self.checker.check_started.connect(self.check_started)
self.checker.check_successful.connect(self.check_successful)
self.checker.check_failed.connect(self.check_failed)

self.checker.start()

1 个回答

0

看起来你遇到的主要问题是你在调用 time.sleep() 这个函数。我没有看到你在哪里定义了时间,但如果这是正常的 Python 时间模块,它会让 Python 解释器暂停,这可能就是问题的原因。

因为你不想把 Python 的线程和 Qt 的线程混在一起,我建议你使用 QThread.wait()。这样做会让事情变得简单很多:

def run(self):
    while True:
        self.check()
        self.wait(self.check_frequency) # or do necessary unit conversion

撰写回答