Проблема с дублированием функций и глобальными переменными в приложении PySide6 функция печати дня и месяца дублируется при нажатии кнопки

0

Вопрос

Я новичок, и я знаю, что есть что-то я пропустил, но я не знаю, что именно, поэтому у меня есть приложение PySide6, и я создал функцию для создания календаря в QTableWidget с помощью модуля "календарь" в Python все работало нормально, но проблема возникла, когда я попытался добавить кнопки навигации, чтобы получить следующий и предыдущий месяц: Это моя функция:

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

from functools import partial

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)
        global widgets
        widgets = self.ui

        # Calender generator
        self.calender_gen(mm,yy)



    def calender_gen(self, mm_g, yy_g):
        # Creat table rows and columns
        widgets.tableWidget_3.setRowCount(5)
        widgets.tableWidget_3.setColumnCount(7)

        # Table header labels
        week_list = ["Sat","Sun","Mon","Tue","Wed","Thu","Fri"]
        widgets.tableWidget_3.setHorizontalHeaderLabels(week_list)

        # Start inserting days of the month into the table
        row = 0
        col = 0
        for week in calendar.monthcalendar(yy_g,mm_g):
            for day in week:
                if day == 0:
                    widgets.tableWidget_3.setItem(row,col,QTableWidgetItem(" "))
                else:
                    widgets.tableWidget_3.setItem(row,col,QTableWidgetItem(str(day)))
                col += 1
            row += 1
            col = 0
        print(mm_g,yy_g)
        # Connect Buttons to function
        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))

    def next_calendar_butt(self,mm_new, yy_new):
        mm_new += 1
        if mm_new > 12:
            mm_new = 1
            yy_new += 1

        widgets.tableWidget_3.setRowCount(0)
        widgets.tableWidget_3.setColumnCount(0)
        self.calender_gen(mm_new,yy_new)

    def prev_calendar_butt(self,mm_g_new,yy_g_new):
        mm_g_new -= 1
        if mm_g_new == 0:
            mm_g_new = 12
            yy_g_new -= 1

        widgets.tableWidget_3.setRowCount(0)
        widgets.tableWidget_3.setColumnCount(0)
        self.calender_gen(mm_g_new,yy_g_new)

Когда я запускаю приложение, календарь отображается в таблице, как на изображении, изображении таблицы графического интерфейса

Консоль вывода Консоли печатает 11 2021

Когда я нажимаю на кнопку 3 в первый раз, она работает нормально и печатает "12 2021" в консоли, консоль печатает 12 2021 Но после того, как я снова нажимаю на ту же кнопку, начинается дублирование: консоль печатает "12 2021 1 2022" консоль печатает 12 2021 1 2022 Если я нажму еще раз, он напечатает '12 2021 1 2022 1 2022 2 2022' как и на изображении, введите описание изображения здесь с каждым щелчком мыши, оно дублирует больше, где должно быть напечатано только одно утверждение, т. е. "2 2022".

Я попытался переместить нижеприведенные строки из функции calendar_gen (), но я не смог передать параметры, даже после объявления глобальных переменных и присвоения их параметрам :

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))

Я пытался это сделать: Внутри функции calendar_gen() я объявил глобальные переменные и назначил их параметрам функции, чтобы создать что-то вроде глобального параметра

global var_mm
global var_yy

var_mm = mm_g
var_yy = yy_g

затем в функции инициализации(self) я помещаю эти 2 строки:

def __init__(self):
    widgets.pushButton_3.clicked.connect(partial(self.next_calendar_butt,var_mm,var_yy))
    widgets.pushButton_2.clicked.connect(partial(self.prev_calendar_butt,var_mm,var_yy))

Но это не сработало в консоли, она печатает "11 2021", когда я запускаю приложение, затем, когда я нажимаю кнопку 3, она печатает "12 2021", а когда я снова нажимаю на нее, она снова печатает "12 2021" и так далее То же самое с другой кнопкой, на которой снова и снова выводится "10 2021"

global-variables pyqt pyqt6 pyside6
2021-11-21 22:34:07
1

Лучший ответ

0

Соединения сигналов Qt не являются исключительными (по умолчанию), и сигнал может быть подключен к одной и той же функции более одного раза.

Поскольку вы подключаете clicked сигналы кнопок в calender_gen, каждый раз, когда вызывается эта функция, вы добавляете дополнительное соединение к этим сигналам. В результате подключенные функции будут вызываться столько раз, сколько они были подключены каждый раз при подаче сигнала.

Правильным решением является подключение к функциям, которые переключали бы месяц и сохраняли ссылку на текущий месяц для вычисления "нового" месяца.

Поскольку функции почти идентичны, лучше сгруппировать их в уникальную функцию, а затем соединить сигналы с отдельными функциями, которые в конечном итоге вызовут эту предыдущую функцию с соответствующим параметром:

class MainWindow(QMainWindow):
    def __init__(self):
        # ...
        self.calender_gen(mm,yy)

        self.pushButton_2.clicked.connect(self.prev_month)
        self.pushButton_3.clicked.connect(self.next_month)

    def calender_gen(self, mm_g, yy_g):
        # Creat table rows and columns
        self.tableWidget_3.setRowCount(5)
        self.tableWidget_3.setColumnCount(7)

        # Table header labels
        week_list = ["Sat","Sun","Mon","Tue","Wed","Thu","Fri"]
        self.tableWidget_3.setHorizontalHeaderLabels(week_list)

        # Start inserting days of the month into the table
        row = 0
        col = 0
        for week in calendar.monthcalendar(yy_g,mm_g):
            for day in week:
                if day == 0:
                    self.tableWidget_3.setItem(row,col,QTableWidgetItem(" "))
                else:
                    self.tableWidget_3.setItem(row,col,QTableWidgetItem(str(day)))
                col += 1
            row += 1
            col = 0

        self.current_month = mm_g
        self.current_year = yy_g

    def prev_month(self):
        self.step_month(-1)

    def next_month(self):
        self.step_month(1)

    def step_month(self, delta):
        mm_new = self.current_month + delta
        mm_year = self.current_year
        if mm_new > 12:
            mm_new = 1
            mm_year += 1
        elif mm_new < 1:
            mm_new = 12
            mm_year -= 1

        self.calender_gen(mm_new, mm_year)

Очевидно, что правильная реализация QCalendarWidget может быть намного проще, поскольку она уже предоставляет большинство функций.

2021-11-21 23:56:46

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................