PyQt5カレンダーのカスタマイズ

今日、私は一見単純なタスクに直面しました。PyQt5のカレンダーウィジェットで、今日の日付が緑色の枠で囲まれるようにします。しかし、ロシア語ではこのトピックに関する資料はまったくなく、英語ではスタックオーバーフローに関する質問は1つだけであることが判明しました。このライブラリに精通している他の開発者の生活を楽にして、この問題をどのように解決したかを説明することにしました。





カレンダーを作成する

カレンダーウィンドウを作成するには、QtCreatorまたはQtDesignerを開きます。[ウィジェットの表示]タブのサイドメニューで、[カレンダー]を選択し、エディターにドラッグします。





.ui



-. Python-, :





pyuic5 path/to/design.ui -o output/path/to/design.py
      
      



, , , , - PyQt. PATH PyQt.





design.py



, .





. , . CustomCalendar.py



, QtWidgets.QCalendarWidget



:





from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt

class MyCalendar(QtWidgets.QCalendarWidget):
    def __init__(self, parent=None):
        QtWidgets.QCalendarWidget.__init__(self, parent)
      
      



:





from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt

class MyCalendar(QtWidgets.QCalendarWidget):
    def __init__(self, parent=None):
        QtWidgets.QCalendarWidget.__init__(self, parent)

    def paintCell(self, painter, rect, date):
        QtWidgets.QCalendarWidget.paintCell(self, painter, rect, date)
        if date == date.currentDate():
            painter.setBrush(QtGui.QColor(0, 200, 200, 50))
            painter.drawRect(rect)
      
      



printCell



:





  • painter



    - Qt,





  • rect



    - , ,





  • date



    - ,





, , . -, . , , , , .





design.py



CustomCalendar



QtWidgets.QCalendarWidget



MyCalendar



:





from PyQt5 import QtCore, QtGui, QtWidgets
from CustomCalendar import MyCalendar


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(600, 502)
        MainWindow.setStyleSheet("")
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.calendarWidget = MyCalendar(self.centralWidget)
        self.calendarWidget.setGeometry(QtCore.QRect(60, 50, 471, 341))
        self.calendarWidget.setObjectName("calendarWidget")
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 600, 22))
        self.menuBar.setObjectName("menuBar")
        MainWindow.setMenuBar(self.menuBar)
        self.mainToolBar = QtWidgets.QToolBar(MainWindow)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


      
      



, . logic.py



:





from PyQt5 import QtWidgets
import sys
import design


class CalendarApp(QtWidgets.QMainWindow, design.Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)


def main():
    app = QtWidgets.QApplication(sys.argv)
    window = CalendarApp()
    window.show()
    app.exec_()


if __name__ == '__main__':
    main()
      
      



, :





, paintRect



painter



, :





def paintCell(self, painter, rect, date):
    QtWidgets.QCalendarWidget.paintCell(self, painter, rect, date)
    if date == date.currentDate():
        painter.setBrush(QtGui.QColor(0, 200, 200, 50))
        painter.setPen(QtGui.QColor(0, 0, 0, 0))
        painter.drawRect(rect)
      
      



元々の仕事は、今日の日付の緑色のボックスを作成することでした。緑のストロークで長方形を描くだけで十分なようです。これを行うには、から線を削除しpainter.setBrush



、目的の色をに設定しますpainter.setPen



しかし、これを行うと、あまり良くないことがわかります。





この長方形に同じ太さの境界線を作成する方法に対する答えが見つかりませんでした。しかし、4本の別々の線を引くことを妨げるものは何もありません。





def paintCell(self, painter, rect, date):
    QtWidgets.QCalendarWidget.paintCell(self, painter, rect, date)
    if date == date.currentDate():
        painter.setPen(QtGui.QPen(QtGui.QColor(0, 200, 200),  2, Qt.SolidLine, Qt.RoundCap))
        painter.drawLine(rect.topRight(), rect.topLeft())
        painter.drawLine(rect.topRight(), rect.bottomRight())
        painter.drawLine(rect.bottomLeft(), rect.bottomRight())
        painter.drawLine(rect.topLeft(), rect.bottomLeft())
      
      



そして最終結果:





他に何ができるか

この助けを借りpainter



て、セルを丸で囲んだりペイントしたりするだけでなく、セルにテキストを書き込んだり、幾何学的な形を描いたりすることもできます。それはすべて、解決される問題と開発者の想像力に依存します。








All Articles