Issue
I'm a beginner and I know there is something I missed but I don't know exactly what, So I have a PySide6 app, and I created a function to generate a calendar in a QTableWidget using calendar module in python all worked fine but the problem came when I tried to add a navigation buttons to get next and previous month: This is my function:
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)
When I run the app the calendar shows in the table as in the image image of the GUI table
The Console output Console prints 11 2021
When I click on pushButton_3 for first time click it works normally and prints '12 2021' in the console console prints 12 2021 But after I click on the same button again it starts duplication: console prints '12 2021 1 2022' console prints 12 2021 1 2022 If I click again it prints '12 2021 1 2022 1 2022 2 2022' as in the image enter image description here with every click it duplicates more where it should only print one statement i.e '2 2022'
I tried to move the below lines out of the calendar_gen() function but I coudn't deliver the parameters, even after declaring global variables and assign them to the parameters :
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))
I've tried to do this: Inside the calendar_gen() function I declared global variables and assigned them to the function parameters in order to create something like a global parameter
global var_mm
global var_yy
var_mm = mm_g
var_yy = yy_g
then in the init(self) function I put those 2 lines:
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))
But this didn't work in the console it prints '11 2021' when I run the app then when I click on pushButton_3 it prints '12 2021' and when I click again on it, it prints '12 2021' again and so on Same with the other button it prints '10 2021' again and again
Solution
Qt signal connections are not exclusive (by default), and a signal can be connected to the same function more than once.
Since you're connecting the clicked
signals of the buttons in calender_gen
, everytime that function is called you're adding a further connection to those signals. The result is that the connected functions will be called as many time as they have been connected every time the signal is emitted.
A proper solution is to connect to the functions that would switch the month and keep a reference to the current month for the "new" month computation.
Since the functions are almost identical, it's better to group them in a unique function, and then connect the signals to separate functions that would eventually call that former function with an appropriate parameter:
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)
Obviously, properly implementing QCalendarWidget might be much simpler, as it already provides most of the functionalities.
Answered By - musicamante
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.