Kustomisasi kalender PyQt5

Hari ini saya menghadapi tugas yang tampaknya sederhana: di widget kalender di PyQt5, buatlah agar tanggal hari ini dikelilingi oleh bingkai hijau. Tetapi ternyata dalam bahasa Rusia tidak ada materi tentang topik ini sama sekali, dan dalam bahasa Inggris hanya ada satu pertanyaan tentang stackoverflow. Saya memutuskan untuk membuat hidup lebih mudah bagi pengembang lain yang baru saja mengenal perpustakaan ini dan menjelaskan bagaimana saya memecahkan masalah ini.





Buat kalender

Untuk membuat jendela kalender, buka Qt Creator atau Qt Designer. Di menu samping di tab Widget Tampilan, pilih Kalender dan seret ke editor:





.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)
      
      



Tugas awalnya adalah membuat kotak hijau untuk tanggal hari ini. Tampaknya cukup menggambar persegi panjang dengan guratan hijau. Untuk melakukan ini, hapus garis dari painter.setBrush



dan atur warna yang diinginkan ke painter.setPen



. Tetapi jika Anda melakukan ini, ternyata tidak terlalu bagus:





Saya tidak menemukan jawaban tentang bagaimana membuat perbatasan dengan ketebalan yang sama untuk persegi panjang ini. Tetapi tidak ada yang mencegah Anda menggambar empat garis terpisah:





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())
      
      



Dan hasil akhirnya:





Apa lagi yang bisa dilakukan

Dengan bantuan, painter



Anda tidak hanya dapat melingkari atau melukis di atas sel, tetapi juga menulis beberapa teks di dalamnya atau menggambar bentuk geometris. Itu semua tergantung pada masalah yang diselesaikan dan imajinasi pengembang.








All Articles