Пример #1
0
def test_get_day_events():
    """
    Tests the Model 'get_day_events' method
    """
    print("get_day_events")
    c = CalendarModel(1, 2019)
    print(c.get_day_events(12))
Пример #2
0
class MainViewController(QMainWindow):
    '''
    The MainViewController is the parent window of every other window. It's GUI is always present and visible,
    but not always clickable when child windows have the focus. The window has 42 day buttons in a grid which
    can be clicked to open a child view, if they are valid buttons for a given month and year. There are also
    buttons to change the displayed month and year, as well as an "add event" button to add events to the calendar.
    '''
    def __init__(self):
        #Super init and load the ui
        super(MainViewController, self).__init__()
        loadUi(ui[0], self)
        #PyQT has bugs when the buttonGroup is set to exclusive
        self.buttonGroup_days.setExclusive(False)
        #Setup Model
        now = datetime.date.today()
        self.m = CalendarModel(now.month, now.year)
        #Set title of window
        self.setWindowTitle('Calendar')
        #Connect Buttons
        self.pushButton_plus.clicked.connect(self.next_year)
        self.pushButton_minus.clicked.connect(self.previous_year)
        self.pushButton_add.clicked.connect(self.add_event_button)
        self.pushButton_next.clicked.connect(self.next_month_button)
        self.pushButton_previous.clicked.connect(self.previous_month_button)
        #Button group buttons
        for button in self.buttonGroup_days.buttons():
            button.clicked.connect(self.day_button)
        #Update based on model data
        self.refresh()

    def refresh(self):
        '''
        args: N/A
        returns: N/A
        side effects: labels and buttons update to match the model
        description: refresh is the function called by the view controller whenever model data
        has changed. This way, the user always sees a representation of the current model.
        '''
        #Set: Month, Year
        self.label_year.setText(str(self.m.year))
        self.label_month.setText(calendar.month_name[(self.m.month)])
        #An example of monthrange, the function that returns the number of days in a month and the day
        #the month starts on:
        #>>> calendar.monthrange(2019, 1)
        #>>> (1, 31)
        # "(1, 31)" is saying: (Tuesday, 31 days in that month)
        first_day, month_Days = calendar.monthrange(self.m.year, self.m.month)
        #Set: days
        for button in self.buttonGroup_days.buttons():
            #This line requires knowledge of the .ui file: the day buttons have names like pushButton_*
            #where "*" is some string of an int 1-42. So this line extracts that int and puts it in x
            x = (int(button.objectName().split('_')[1]))
            #Fixing off by one error
            startDate = first_day + 1
            #Getting last day
            endDate = month_Days + first_day
            #Setting valid days/invalid days
            if (x < startDate or x > endDate):
                button.setText('')
                button.setEnabled(False)
            else:
                button.setEnabled(True)
                events = self.m.get_day_events(x - first_day)
                if events == None:
                    event_str = ""
                else:
                    event_str = "\nEvents: " + str(len(events))
                button.setText(str(x - first_day) + "\n" + event_str)
        return

    #
    #pyqtSlots (the decorator wraps these functions in a function connecting them to signals)
    #
    @pyqtSlot()
    def add_event_button(self):  #Opens the add_event pop up window
        #TODO: Either use this sub-wrapper or delete it
        self.add_window_h()
        self.refresh()
        return

    @pyqtSlot()
    def next_month_button(self):
        self.m.next_month()
        self.refresh()
        return

    @pyqtSlot()
    def previous_month_button(self):
        self.m.prev_month()
        self.refresh()
        return

    @pyqtSlot()
    def day_button(self):
        abstract_button = self.sender()
        day = abstract_button.text().split("\n")[0]

        events = self.m.get_day_events(day)
        day_dialog = Day_Window(self.m, day, events)
        day_dialog.exec()

        abstract_button.toggle()
        self.refresh()
        return

    @pyqtSlot()
    def previous_year(self):
        '''
        side effects: the model's year goes down by 1 and the view is refreshed
        description:  Call on the model to decrease the year by 1
        '''
        self.m.year -= 1
        self.refresh()

    @pyqtSlot()
    def next_year(self):
        '''
        side effects: the model's year goes up by 1 and the view is refreshed
        description:  Call on the model to increase the year by 1
        '''
        self.m.year += 1
        self.refresh()

    #Window helpers
    def add_window_h(self):
        '''
        side effects: opens
        description: Storing values at datetime objects means we can easily use datetime methods for various
        returns: a boolean whether self.accept() was called or not. (Whether the user clicked save or the "X")
        '''
        addDialog = Event_Add_Window(self.m)
        if addDialog.exec():
            return (True)
        return False