You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5中调用另一函数时如何终止指定定时函数?

解决PyQt5定时任务冲突的问题

我来帮你搞定这个问题!你现在遇到的核心问题是两个独立的threading.Timer任务没有互相控制的机制,导致点击两个按钮后,两个定时更新表格的操作会同时执行,最终造成内容重叠。

解决方案思路

我们需要在你的窗口类里维护一个当前活跃的定时器对象,每次启动新的定时任务前,先取消掉之前正在运行的定时器(如果有的话)。这样就能保证同一时间只有一个定时任务在更新表格,不会出现冲突。

修改后的完整代码

class YourMainWindowClass(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        # 初始化当前定时器对象,用于跟踪活跃的定时任务
        self.current_timer = None
        
        self.pushButton_1.clicked.connect(self.fun)
        self.pushButton_2.clicked.connect(self.fun2)

    def fun(self):
        print("1...")
        # 先取消之前的定时器(如果存在)
        if self.current_timer is not None:
            self.current_timer.cancel()
        # 创建新的定时器并保存到current_timer
        self.current_timer = threading.Timer(5.0, self.fun)
        self.current_timer.start()

        # 读取Excel数据并更新表格
        ex_data = pd.read_excel('bank2.xlsm', sheet_name=2, skiprows=5, nrows=18, usecols='D:V')
        df = pd.DataFrame(ex_data).replace(np.nan, '', regex=True)
        
        self.tableWidget.setColumnCount(len(df.columns))
        self.tableWidget.setRowCount(len(df.index))
        for i in range(len(df.index)):
            for j in range(len(df.columns)):
                self.tableWidget.setItem(i, j, QtWidgets.QTableWidgetItem(str(df.iloc[i, j])))
        self.tableWidget.resizeColumnsToContents()

    def fun2(self):
        print("2...")
        # 先取消之前的定时器(如果存在)
        if self.current_timer is not None:
            self.current_timer.cancel()
        # 创建新的定时器并保存到current_timer
        self.current_timer = threading.Timer(5.0, self.fun2)
        self.current_timer.start()

        # 读取Excel数据并更新表格
        ex_data = pd.read_excel('bank2.xlsm', sheet_name=3, skiprows=5, nrows=18, usecols='D:V')
        df = pd.DataFrame(ex_data).replace(np.nan, '', regex=True)
        
        self.tableWidget.setColumnCount(len(df.columns))
        self.tableWidget.setRowCount(len(df.index))
        for i in range(len(df.index)):
            for j in range(len(df.columns)):
                self.tableWidget.setItem(i, j, QtWidgets.QTableWidgetItem(str(df.iloc[i, j])))
        self.tableWidget.resizeColumnsToContents()

关键修改说明

  1. 添加self.current_timer属性:在类的初始化方法里声明这个变量,用来记录当前正在运行的定时器实例。
  2. 取消旧定时器:在每个fun和fun2函数开头,先检查self.current_timer是否存在,如果存在就调用cancel()方法终止它,这样旧的定时任务就不会再触发后续的执行了。
  3. 移除不必要的重复操作:我去掉了self.retranslateUi(MainWindow)和QtCore.QMetaObject.connectSlotsByName(MainWindow),这两个方法一般只需要在初始化或者语言切换时调用,每次更新表格都调用会造成不必要的性能开销。

效果说明

现在当你点击pushButton_1时,会自动终止fun2的定时任务(如果它在运行),然后启动fun的5秒循环更新;点击pushButton_2时同理,只会保留当前按钮对应的定时任务,表格内容就不会再重叠啦!

内容的提问来源于stack exchange,提问作者ClaWnN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:08:24