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()
关键修改说明
- 添加
self.current_timer属性:在类的初始化方法里声明这个变量,用来记录当前正在运行的定时器实例。 - 取消旧定时器:在每个
fun和fun2函数开头,先检查self.current_timer是否存在,如果存在就调用cancel()方法终止它,这样旧的定时任务就不会再触发后续的执行了。 - 移除不必要的重复操作:我去掉了
self.retranslateUi(MainWindow)和QtCore.QMetaObject.connectSlotsByName(MainWindow),这两个方法一般只需要在初始化或者语言切换时调用,每次更新表格都调用会造成不必要的性能开销。
效果说明
现在当你点击pushButton_1时,会自动终止fun2的定时任务(如果它在运行),然后启动fun的5秒循环更新;点击pushButton_2时同理,只会保留当前按钮对应的定时任务,表格内容就不会再重叠啦!
内容的提问来源于stack exchange,提问作者ClaWnN
相关产品推荐
相关产品推荐

