PyQt5 QCalendarWidget – 使用完毕后关闭

  • Post category:Python

让我为你讲解一下PyQt5 QCalendarWidget的使用攻略。

1. QCalendarWidget简介

QCalendarWidget是PyQt5中一个非常有用的小部件,它能够显示日历,并允许用户选择日期。在使用QCalendarWidget时,我们通常需要控制它的显示和关闭,以便让用户更加便捷地使用日历功能。

2. QCalendarWidget的创建和显示

在PyQt5中使用QCalendarWidget非常简单,我们可以通过以下代码进行创建和显示:

from PyQt5.QtWidgets import QApplication, QWidget, QCalendarWidget

app = QApplication([])
widget = QWidget()
calendar = QCalendarWidget(widget)
calendar.setGeometry(0, 0, 320, 280)
widget.show()
app.exec_()

在上述代码中,我们首先创建了一个QApplication实例,然后创建了一个QWidget实例,并将QCalendarWidget放在QWidget实例中,最后设置了QWidget的大小并显示出来。当我们调用QApplication的exec_()方法时,QCalendarWidget就会开始运行。

3. 关闭QCalendarWidget

当用户完成对应用程序的操作后,我们通常需要关闭QCalendarWidget窗口,以便让应用程序回到主界面。在PyQt5中,我们可以通过以下代码来关闭QCalendarWidget:

from PyQt5.QtWidgets import QApplication, QWidget, QCalendarWidget

app = QApplication([])

def handle_calendar_close():
    widget.close()

widget = QWidget()
calendar = QCalendarWidget(widget)
calendar.setGeometry(0, 0, 320, 280)
calendar.selectionChanged.connect(handle_calendar_close)
widget.show()

app.exec_()

在上述代码中,我们创建了一个handle_calendar_close()方法,并将它连接到了QCalendarWidget的selectionChanged信号上。当用户选择了日期并关闭了QCalendarWidget,handle_calendar_close()方法就会被调用,从而关闭了QWidget实例。

示例1

首先,我们需要导入PyQt5中相关的模块:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QCalendarWidget
from PyQt5.QtCore import QDate
import sys

然后,我们可以通过下面的代码创建一个名为CalendarDemo的类,在类的构造函数中添加QCalendarWidget以及关闭按钮(QPushButton)。

class CalendarDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 添加垂直布局管理器
        vbox = QVBoxLayout()

        # 添加QCalendarWidget小部件
        self.calendar = QCalendarWidget(self)
        self.calendar.setMinimumDate(QDate(1900, 1, 1))
        self.calendar.setMaximumDate(QDate(2100, 1, 1))
        self.calendar.setGridVisible(True)
        vbox.addWidget(self.calendar)

        # 添加关闭按钮
        btn = QPushButton('Close This Dialog', self)
        btn.clicked.connect(self.handle_close_btn)
        vbox.addWidget(btn)

        # 将垂直布局管理器应用到主窗口中
        self.setLayout(vbox)

在上述代码中,我们创建了QCalendarWidget小部件,并将它添加到了垂直布局管理器中。我们还添加了一个“Close This Dialog”按钮,并将它连接到了handle_close_btn函数上。

    def handle_close_btn(self):
        selected_date = self.calendar.selectedDate()
        print('You selected date: ', selected_date.toString())
        self.close()

handle_close_btn函数中,我们获取了QCalendarWidget中用户选择的日期,并输出到终端上。然后关闭了这个对话框(QWidget)。

完整代码:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QCalendarWidget
from PyQt5.QtCore import QDate
import sys

class CalendarDemo(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 添加垂直布局管理器
        vbox = QVBoxLayout()

        # 添加QCalendarWidget小部件
        self.calendar = QCalendarWidget(self)
        self.calendar.setMinimumDate(QDate(1900, 1, 1))
        self.calendar.setMaximumDate(QDate(2100, 1, 1))
        self.calendar.setGridVisible(True)
        vbox.addWidget(self.calendar)

        # 添加关闭按钮
        btn = QPushButton('Close This Dialog', self)
        btn.clicked.connect(self.handle_close_btn)
        vbox.addWidget(btn)

        # 将垂直布局管理器应用到主窗口中
        self.setLayout(vbox)

    def handle_close_btn(self):
        selected_date = self.calendar.selectedDate()
        print('You selected date: ', selected_date.toString())
        self.close()


if __name__ == '__main__':
    app = QApplication([])
    demo = CalendarDemo()
    demo.show()
    sys.exit(app.exec_())

示例2

下面我们将通过一个更加生动的示例来演示如何使用QCalendarWidget。该示例中,我们将使用QCalendarWidget小部件模拟一个“日程安排”应用程序,用户可以创建、编辑和删除日程。

首先,我们需要导入所需要的模块:

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QCalendarWidget, QInputDialog, QLineEdit, QPushButton, QMessageBox
from PyQt5.QtCore import QDate
import sys

然后,我们可以通过下面的代码创建一个名为ScheduleApp的类,在类的构造函数中添加所有必要的小部件。

class ScheduleApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 添加垂直布局管理器
        vbox = QVBoxLayout()

        # 添加QCalendarWidget小部件
        self.calendar = QCalendarWidget(self)
        self.calendar.setMinimumDate(QDate(1900, 1, 1))
        self.calendar.setMaximumDate(QDate(2100, 1, 1))
        self.calendar.setGridVisible(True)
        vbox.addWidget(self.calendar)

        # 添加按钮
        hbox = QHBoxLayout()

        self.add_btn = QPushButton('Add', self)
        self.add_btn.clicked.connect(self.handle_add_btn)
        hbox.addWidget(self.add_btn)

        self.edit_btn = QPushButton('Edit', self)
        self.edit_btn.clicked.connect(self.handle_edit_btn)
        hbox.addWidget(self.edit_btn)

        self.del_btn = QPushButton('Delete', self)
        self.del_btn.clicked.connect(self.handle_del_btn)
        hbox.addWidget(self.del_btn)

        vbox.addLayout(hbox)

        # 将垂直布局管理器应用到主窗口中
        self.setLayout(vbox)

在上述代码中,我们添加了QCalendarWidget小部件,并在布局管理器中添加了添加、编辑和删除按钮。我们将这些按钮连接到了相关的处理函数上。

现在,我们需要实现按钮的处理函数。

    def handle_add_btn(self):
        date = self.calendar.selectedDate().toString()
        text, ok = QInputDialog.getText(self, 'Add Item', 'Enter your item:')
        if ok and text:
            self.calendar.setStyleSheet('QCalendarWidget QTableView::item:selected {background-color: white;}')
            self.calendar.setSelectedDate(QDate.fromString(date))
            item_text = text.title()
            index = self.calendar.findItems(item_text, QtCore.Qt.MatchExactly)
            if index:
                QMessageBox.warning(self, 'Duplicate Item', 'This item is already in the calendar!', QMessageBox.Ok)
            else:
                self.calendar.findChild(QtWidgets.QTableView).scrollToBottom()
                self.calendar.model().insertRow(self.calendar.rowCount())
                self.calendar.model().setData(self.calendar.model().index(self.calendar.rowCount() - 1, 0), QDate.fromString(date))
                self.calendar.model().setData(self.calendar.model().index(self.calendar.rowCount() - 1, 1), item_text)

    def handle_edit_btn(self):
        date = self.calendar.selectedDate().toString()
        model = self.calendar.model()
        indices = self.calendar.selectedIndexes()
        if indices:
            for i in indices:
                row = i.row()
                column = i.column()
                value = i.data()
                if column == 0:
                    column_name = 'Date'
                elif column == 1:
                    column_name = 'Item'
                text, ok = QInputDialog.getText(self, 'Edit ' + column_name, 'Enter new {}:'.format(column_name), QLineEdit.Normal, value)
                if ok and text:
                    item_text = text.title()
                    if column == 0:
                        model.setData(model.index(row, column), QDate.fromString(text))
                    elif column == 1:
                        index = self.calendar.findItems(item_text, QtCore.Qt.MatchExactly)
                        if index and QDate.fromString(date).toString() == model.data(model.index(index[0].row(), 0)):
                            QMessageBox.warning(self, 'Duplicate Item', 'This item is already in the calendar!', QMessageBox.Ok)
                        else:
                            model.setData(model.index(row, column), item_text)

    def handle_del_btn(self):
        date = self.calendar.selectedDate().toString()
        model = self.calendar.model()
        indices = self.calendar.selectedIndexes()
        if indices:
            ok = QMessageBox.warning(self, 'Confirm Delete', 'Do you really want to delete this item?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if ok == QMessageBox.Yes:
                for i in indices:
                    row = i.row()
                    column = i.column()
                    model.removeRow(row)

在上述代码中,我们定义了三个处理函数,分别是:

  • handle_add_btn():用于添加日程。
  • handle_edit_btn():用于编辑日程。
  • handle_del_btn():用于删除日程。

在这些处理函数中,我们首先获取用户选择的日期,并根据需要创建、编辑或删除日程。如果用户输入的日程名称已经存在,则会提示用户这个日程已经存在。

现在,我们已经完成了全部的代码,我们可以运行这个应用程序并测试一下了。运行后,我们可以看到日历已经显示在应用程序中。当我们单击添加按钮时,会弹出一个对话框,我们可以在对话框中输入新的日程并保存。当我们单击编辑按钮时,可以编辑已经存在的日程,并进行保存。当我们单击删除按钮时,可以删除当前选择的日程。

完整代码:

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QCalendarWidget, QInputDialog, QLineEdit, QPushButton, QMessageBox
from PyQt5.QtCore import QDate
import sys

class ScheduleApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        # 添加垂直布局管理器
        vbox = QVBoxLayout()

        # 添加QCalendarWidget小部件
        self.calendar = QCalendarWidget(self)
        self.calendar.setMinimumDate(QDate(1900, 1, 1))
        self.calendar.setMaximumDate(QDate(2100, 1, 1))
        self.calendar.setGridVisible(True)
        vbox.addWidget(self.calendar)

        # 添加按钮
        hbox = QHBoxLayout()

        self.add_btn = QPushButton('Add', self)
        self.add_btn.clicked.connect(self.handle_add_btn)
        hbox.addWidget(self.add_btn)

        self.edit_btn = QPushButton('Edit', self)
        self.edit_btn.clicked.connect(self.handle_edit_btn)
        hbox.addWidget(self.edit_btn)

        self.del_btn = QPushButton('Delete', self)
        self.del_btn.clicked.connect(self.handle_del_btn)
        hbox.addWidget(self.del_btn)

        vbox.addLayout(hbox)

        # 将垂直布局管理器应用到主窗口中
        self.setLayout(vbox)

    def handle_add_btn(self):
        date = self.calendar.selectedDate().toString()
        text, ok = QInputDialog.getText(self, 'Add Item', 'Enter your item:')
        if ok and text:
            self.calendar.setStyleSheet('QCalendarWidget QTableView::item:selected {background-color: white;}')
            self.calendar.setSelectedDate(QDate.fromString(date))
            item_text = text.title()
            index = self.calendar.findItems(item_text, QtCore.Qt.MatchExactly)
            if index:
                QMessageBox.warning(self, 'Duplicate Item', 'This item is already in the calendar!', QMessageBox.Ok)
            else:
                self.calendar.findChild(QtWidgets.QTableView).scrollToBottom()
                self.calendar.model().insertRow(self.calendar.rowCount())
                self.calendar.model().setData(self.calendar.model().index(self.calendar.rowCount() - 1, 0), QDate.fromString(date))
                self.calendar.model().setData(self.calendar.model().index(self.calendar.rowCount() - 1, 1), item_text)

    def handle_edit_btn(self):
        date = self.calendar.selectedDate().toString()
        model = self.calendar.model()
        indices = self.calendar.selectedIndexes()
        if indices:
            for i in indices:
                row = i.row()
                column = i.column()
                value = i.data()
                if column == 0:
                    column_name = 'Date'
                elif column == 1:
                    column_name = 'Item'
                text, ok = QInputDialog.getText(self, 'Edit ' + column_name, 'Enter new {}:'.format(column_name), QLineEdit.Normal, value)
                if ok and text:
                    item_text = text.title()
                    if column == 0:
                        model.setData(model.index(row, column), QDate.fromString(text))
                    elif column == 1:
                        index = self.calendar.findItems(item_text, QtCore.Qt.MatchExactly)
                        if index and QDate.fromString(date).toString() == model.data(model.index(index[0].row(), 0)):
                            QMessageBox.warning(self, 'Duplicate Item', 'This item is already in the calendar!', QMessageBox.Ok)
                        else:
                            model.setData(model.index(row, column), item_text)

    def handle_del_btn(self):
        date = self.calendar.selectedDate().toString()
        model = self.calendar.model()
        indices = self.calendar.selectedIndexes()
        if indices:
            ok = QMessageBox.warning(self, 'Confirm Delete', 'Do you really want to delete this item?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if ok == QMessageBox.Yes:
                for i in indices:
                    row = i.row()
                    column = i.column()
                    model.removeRow(row)


if __name__ == '__main__':
    app = QApplication([])
    demo = ScheduleApp()
    demo.show()
    sys.exit(app.exec_())

以上就是PyQt5 QCalendarWidget的完整使用攻略。