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

PySide6日历应用点击导航按钮函数重复执行、全局变量配置问题

问题根因

每次调用calender_gen方法生成日历时,都会重复给上月、下月按钮绑定点击事件,Qt的信号槽绑定为累加机制,旧绑定不会自动覆盖清除,因此单次点击按钮会触发所有历史绑定的槽函数,最终出现打印多组年月数据、重复执行的问题。
之前将绑定逻辑放到__init__中不生效的原因是:functools.partial传递的是绑定时的参数值(值拷贝),而非变量引用,后续修改年月变量时,partial中保存的仍是初始绑定的年月值,因此只会跳转一次就不再变化。

修复方案

推荐方案(最优)

将当前年月存储为类实例属性,__init__中仅绑定一次按钮事件,直接操作实例属性修改年月,无需重复绑定信号槽。
修改后代码如下:

import sys
import os
import platform
import datetime as dt
import time
import calendar

from PySide6 import *
from PySide6 import QtGui
from PySide6 import QtWidgets
from PySide6 import QtCore
from PySide6.QtGui import QColor

yy = int(dt.datetime.now().strftime("%Y"))
mm = int(dt.datetime.now().strftime("%m"))

class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.widgets = self.ui

        # 存储当前年月为实例属性
        self.current_mm = mm
        self.current_yy = yy

        # 仅在初始化时绑定一次按钮事件
        self.widgets.pushButton_3.clicked.connect(self.next_calendar_butt)
        self.widgets.pushButton_2.clicked.connect(self.prev_calendar_butt)

        # 生成初始日历
        self.calender_gen()

    def calender_gen(self):
        # 重置表格行列
        self.widgets.tableWidget_3.setRowCount(5)
        self.widgets.tableWidget_3.setColumnCount(7)

        # 表格表头标签
        week_list = ["Sat","Sun","Mon","Tue","Wed","Thu","Fri"]
        self.widgets.tableWidget_3.setHorizontalHeaderLabels(week_list)

        # 插入当月日期到表格
        row = 0
        col = 0
        for week in calendar.monthcalendar(self.current_yy, self.current_mm):
            for day in week:
                if day == 0:
                    self.widgets.tableWidget_3.setItem(row,col,QTableWidgetItem(" "))
                else:
                    self.widgets.tableWidget_3.setItem(row,col,QTableWidgetItem(str(day)))
                col += 1
            row += 1
            col = 0
        print(self.current_mm, self.current_yy)

    def next_calendar_butt(self):
        self.current_mm += 1
        if self.current_mm > 12:
            self.current_mm = 1
            self.current_yy += 1
        # 重新生成日历
        self.calender_gen()

    def prev_calendar_butt(self):
        self.current_mm -= 1
        if self.current_mm == 0:
            self.current_mm = 12
            self.current_yy -= 1
        # 重新生成日历
        self.calender_gen()

快速修复方案(不改整体结构)

如果不想调整原有代码结构,可以在每次绑定信号前先断开旧的连接,避免重复绑定:
在calender_gen方法内绑定按钮的代码前,添加如下断开逻辑:

# 先断开旧的信号连接,避免重复绑定
try:
    widgets.pushButton_3.clicked.disconnect()
    widgets.pushButton_2.clicked.disconnect()
except RuntimeError:
    # 首次绑定时没有旧连接,忽略异常
    pass
# 再绑定新的槽函数
widgets.pushButton_3.clicked.connect(partial(self.next_calendar_butt,mm_g,yy_g))
widgets.pushButton_2.clicked.connect(partial(self.prev_calendar_butt,mm_g,yy_g))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 23:06:06