0

I have been creating this calendar object with the possibility to 'assign' events - these are anything the user wants, from picking up milk from the corner shop to organising a wedding to setting out an exam timetable - to specific dates.

Here is a bare-bones version of my application code (written using Python 3.4.3 and PyQt 4.11.4) on which it's possible to recreate the error I continually experience (shown below):

# Imports all the needed modules.
import sys
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *

# Defines variables needed for the settings dialog.
currentDate = QtCore.QDate.currentDate()
maxDate = QtCore.QDate(2999, 12, 31)

class AppSettingsDialog(QtGui.QDialog): # The Settings dialog.
    def __init__(self, parent=None):
        # The initializer function for the dialog.
        super(AppSettingsDialog, self).__init__(parent)
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.calendarSpecificSettings()

        mainGridLayout = QtGui.QGridLayout()
        mainGridLayout.addWidget(self.calendarSpecificSettingsBox,
                                 0, 0)
        self.setLayout(mainGridLayout)

        self.exec_()

    def calendarSpecificSettings(self):
        # Creates a separator to put the widgets in.
        self.calendarSpecificSettingsBox = QtGui.QGroupBox(
            'Calendar Specific')

        self.maxDateLabel = QtGui.QLabel('Ma&ximum Date')
        self.maxDateEdit = QtGui.QDateEdit()
        self.maxDateEdit.setDisplayFormat('dd MMM yyyy')
        self.maxDateEdit.setDateRange(currentDate, maxDate)
        self.maxDateEdit.setDate(maxDate)
        self.maxDateLabel.setBuddy(self.maxDateEdit)
        self.maxDateEdit.dateChanged.connect(self.maximumDateChanged)
                    # Call to function error here ^

        self.calendarSpecificGridLayout = QtGui.QGridLayout()
        self.calendarSpecificGridLayout.addWidget(self.maxDateLabel,
                                                  0, 0)
        self.calendarSpecificGridLayout.addWidget(self.maxDateEdit,
                                                  0, 1)

        self.calendarSpecificSettingsBox.setLayout(
            self.calendarSpecificGridLayout)

    def maximumDateChanged(self, date): 
        MainWindow.calWidget.setMaximumDate(date)
        # ^This is the line that causes the error. I have multiple
        # 'MainWindow' calls - one for each of the settings I want
        # to change.

class MainWindow(QtGui.QMainWindow): # The main window.
    def __init__(self):
        # The initializer function for the window.
        super(MainWindow, self).__init__()
        mainMenu = self.menuBar()

        menuOptions = mainMenu.addMenu('Options')
        actionSettings = QtGui.QAction('Settings...', self)
        actionSettings.triggered.connect(self.appSettings)
        menuOptions.addAction(actionSettings)

        calWidget = QtGui.QCalendarWidget(self)
        calWidget.resize(300, 300)
        calWidget.setGridVisible(True)
        calWidget.setNavigationBarVisible(True)
        self.setCentralWidget(calWidget)

        self.statusBar().setSizeGripEnabled(True)
        self.statusBar().showMessage('Ready', 5000)

    def appSettings(self):
        # The function that invokes the dialog.
        AppSettingsDialog()

# One way to initialize the application.
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    GUI = MainWindow()
    GUI.show()
    sys.exit(app.exec_())

The problem for me is as follows:

I am attempting to make sure the setting changes in the settings dialog actually apply to the calendar but, when I change any of them, the following error constantly appears (it's haunting my dreams already):

Traceback (most recent call last):
  File "C:/Python34/CalTest.py", line 50, in maximumDateChanged
    mainWindow.calWidget.setMaximumDate(date)
AttributeError: type object 'MainWindow' has no attribute 'calWidget'

What makes it worse is that I don't actually understand the error. Does it mean calWidget isn't a property of MainWindow? Is it because the Settings class is separate from the MainWindow class? I've researched on this forum (and outside it) on anything that relates on it, but nothing I found relates to my problem. My research includes:

Python Attribute Error: type object has no attribute

Type Object has no attribute

Error: type object 'Keys' has no attribute 'chord'

but nothing I found could solve my problem (believe me I tried).

Also, while I'm at it, how could I receive several inputs from the user through a dialog window? Would a dictionary of dictionaries be suitable or is there something else that could make my life easier? This is because I have yet to implement the function to add a new event related to a specific date and having a starting point would be a blessing - this whole situation has probably been an unnecessary nightmare. I also feel that if I get this fixed, I will be able to recreate the same structure in the other actions (which include adding, editing, saving and deleting one or all the events created).

Any help would be greatly appreciated. Thank you in advance.

2
  • Does it mean calWidget isn't a property of mainWindow? - Yes Commented May 1, 2016 at 13:55
  • But I created calWidget within the class mainWindow. Commented May 1, 2016 at 14:01

1 Answer 1

1

You can access calWidget like this in your function:

def maximumDateChanged(self, date): 
        mainWindow.centralWidget().setMaximumDate(date)
        # ^This is the line that causes the error. I have multiple
        # 'mainWindow' calls - one for each of the settings I want
        # to change.

My answer was incorrect as I mistook mainWindow to be an instance based on convention. In your case to handle change on MainWindow through the dialog, you need to change the appSettings method and define the maximumDateChanged in the mainWindow class like this

def appSettings(self):
        # The function that invokes the dialog.
        appSettingsDialog = AppSettingsDialog()
        appSettingsDialog.maxDateEdit.dateChanged.connect(self.maximumDateChanged)

def maximumDateChanged(self, date):
        self.centralWidget().setMaximumDate(date)
Sign up to request clarification or add additional context in comments.

8 Comments

When I type in what you gave me, I get another error: TypeError: QMainWindow.centralWidget(): first argument of unbound method must have type 'QMainWindow'
I also attempted variations of the code above, including without the brackets, with 'mainWindow' inside the brackets and 'QtGui.QMainWindow' but the same error maintains.
When adding your edited code above, I get the same error as above (in my first comment) when changing a value in the QDateEdit object AND I get another error when closing the settings dialog, which is as follows: RuntimeError: wrapped C/C++ object of type QDateEdit has been deleted - this occurs at line 4 of your code above. Is it anything of concern because I've never seen this error before?
Edited the mainWindow name to MainWindow to conform with the convention I set up regarding class names.
The original error still appears because you have not deleted the line self.maxDateEdit.dateChanged.connect(self.maximumDateChanged) in the Dialog class. Also when the Dialog is closed, you have to disconnect the signal which was created in appSettings method.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.