如何使用 SQL 数据库更改 QCalendarWidget 中单元格的背景颜色

Posted

技术标签:

【中文标题】如何使用 SQL 数据库更改 QCalendarWidget 中单元格的背景颜色【英文标题】:How to change the background colour of a cell in a QCalendarWidget using an SQL database 【发布时间】:2020-03-12 18:04:35 【问题描述】:

这不是How to Output sql data onto a QCalendarWidget的重复问题

这是该问题的附加内容。

这也不是Highlight date interval in a Qt5 Calendar Widget 的副本,因为它只是在用户在实际 QT 页面上选择单元格时突出显示单元格,而不是使用 SQL 数据。这也不是Coloring PyQt5 QCalendarWidget cell and printing data inside the cells 的重复问题,因为答案没有做我希望我的程序做的事情,即使用我的 sql 数据库更改日历特定单元格的背景颜色来做到这一点,以及我无法得到工作的答案。

在第一个链接问题中,我询问用户如何按下日期,如果该日期在 sql 数据库中,它将输出与该日期对应的文本。在一些帮助下,我设法让这个工作。现在我想做的是用蓝色背景突出显示那些日期,就像当前日期用红色背景突出显示一样。

我做的QT页面是这样的:

My QT Page

我的数据库是这样的:

My database

我的代码是这样的:

        # -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Calendar.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets
import sqlite3
import datetime
import PyQt5
from PyQt5.QtCore import QDate, Qt
from PyQt5.QtGui import (QColor, QFont, QTextCharFormat, QTextLength,
        QTextTableFormat)
from PyQt5.QtWidgets import (QApplication, QComboBox, QDateTimeEdit,
        QHBoxLayout, QLabel, QMainWindow, QSpinBox, QTextBrowser, QVBoxLayout,
        QWidget)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 900)
        MainWindow.setMinimumSize(QtCore.QSize(0, 0))
        MainWindow.setMaximumSize(QtCore.QSize(1200, 900))
        MainWindow.setStyleSheet("background-color: rgb(200, 200, 200);")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.Header = QtWidgets.QTextEdit(self.centralwidget)
        self.Header.setEnabled(False)
        self.Header.setGeometry(QtCore.QRect(-10, 0, 1300, 110))
        self.Header.setMinimumSize(QtCore.QSize(1300, 110))
        self.Header.setMaximumSize(QtCore.QSize(1300, 110))
        self.Header.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"border-color: rgb(255, 255, 255);\n"
"border-width : 1.2px;\n"
"border-style:inset;")
        self.Header.setObjectName("Header")
        self.LECTURP = QtWidgets.QLabel(self.centralwidget)
        self.LECTURP.setGeometry(QtCore.QRect(512, 2, 180, 61))
        self.LECTURP.setStyleSheet("color: rgb(0, 176, 240);\n"
"font: 8pt \"MS Shell Dlg 2\";\n"
"text-decoration: underline;\n"
"background-color: rgb(255, 255, 255);\n"
"font: 28pt \"Calbri\";\n"
"text-decoration: underline;")
        self.LECTURP.setObjectName("LECTURP")
        self.LecturpBanner = QtWidgets.QLabel(self.centralwidget)
        self.LecturpBanner.setGeometry(QtCore.QRect(320, 60, 561, 31))
        self.LecturpBanner.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"color: rgb(0, 176, 240);\n"
"font: 14pt \"Calibri\";")
        self.LecturpBanner.setObjectName("LecturpBanner")
        self.calendarWidget = QtWidgets.QCalendarWidget(self.centralwidget)
        self.calendarWidget.setGeometry(QtCore.QRect(30, 110, 1141, 661))
        self.calendarWidget.setStyleSheet("alternate-background-color: rgb(255, 255, 255);\n"
"font: 75 16pt \"MS Shell Dlg 2\";\n"
"background-color: rgb(200, 200, 200);\n"
"selection-background-color: rgb(255, 0, 0);")
        self.calendarWidget.setObjectName("calendarWidget")
        self.DateInfoOutput = QtWidgets.QLabel(self.centralwidget)
        self.DateInfoOutput.setGeometry(QtCore.QRect(30, 778, 1141, 97))
        self.DateInfoOutput.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"border-color: rgb(0, 0, 0);\n"
"font: 16pt \"Calibri\";\n"
"border-width : 1.2px;\n"
"border-style:inset;")
        self.DateInfoOutput.setText("")
        self.DateInfoOutput.setObjectName("DateInfoOutput")
        self.WeekNumber = QtWidgets.QLabel(self.centralwidget)
        self.WeekNumber.setGeometry(QtCore.QRect(56, 168, 113, 49))
        self.WeekNumber.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"font: 16pt \"MS Shell Dlg 2\";")
        self.WeekNumber.setObjectName("WeekNumber")
        self.calendarWidget.raise_()
        self.Header.raise_()
        self.LECTURP.raise_()
        self.LecturpBanner.raise_()
        self.DateInfoOutput.raise_()
        self.WeekNumber.raise_()
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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

        self.editor = QTextBrowser()


        self.calendarWidget.clicked[QDate].connect(self.dateClicked)


    def dateClicked(self, clickedDate):
        connection = sqlite3.connect("Calendardatabase.db") 
        crsr = connection.cursor() 
        crsr.execute(
            'SELECT Text FROM Calendar WHERE Day = ? AND Month = ? AND YEAR = ?', 
            (clickedDate.day(), clickedDate.month(), clickedDate.year()))
        result = crsr.fetchone()

        if result:
            self.DateInfoOutput.setText(result[0])
        else:
            self.DateInfoOutput.setText('')


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.LECTURP.setText(_translate("MainWindow", "LECTURP"))
        self.LecturpBanner.setText(_translate("MainWindow", "Lecture, Exam, Coursework, Timetable, Uploader and Reminder Program."))
        self.WeekNumber.setText(_translate("MainWindow", "Week No."))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

我试图跟随你的 cmets,我已经这样做了:

    crsr.execute('SELECT Date FROM Calendar2 WHERE Number = ?', (Count,))
        Dates3 = crsr.fetchone()
        Dates3 = str(Dates3)
        Dates3 = Dates3.replace("'", "")
        Dates3 = Dates3.replace('(', '')
        Dates3 = Dates3.replace(')', '')
        Dates3 = Dates3.replace(',', '')
        print(All_Dates)

        print(Dates3)
        Dates3 = Dates3.replace('/', ',')


        self.dates =  QDate(2020, 3, 20): ["Um Sure"] 

        format = QTextCharFormat() 
        format.setBackground(QColor("salmon")) 
        self.calendarWidget.setDateTextFormat(Dates3, format)

无论我尝试运行此程序,我都会收到此错误:

Message=setDateTextFormat(self, Union[QDate, datetime.date], QTextCharFormat):参数 1 具有意外类型“str”

我尝试使用 self.dates 变量,但也没有用。我不确定如何将日期转换为输出的 QDate 部分可接受的格式。

好吧,一切正常,但是当我做这个 while 循环时,我只是想知道我做错了 python 还是错误的 QT。

    Count = 1 
        while Count <= list3:
            connection = sqlite3.connect("Calendardatabase.db") 
            # This is the code for the database cursor 


            Current_Day = datetime.date.today().strftime("%A,")
            Current_Date = datetime.date.today().strftime("%d")
            Current_Month = datetime.date.today().strftime("%B")


            Combined_Date = ("It is a " + Current_Day + " It is the " + Current_Date + " of " + Current_Month)

            Combined_Date = str(Combined_Date)

            self.DateInfoOutput.setText(Combined_Date)

            cursor = self.editor.textCursor()



            crsr.execute('SELECT Date FROM Calendar2 WHERE Number = ?', (Count,))
            Dates3 = crsr.fetchone()
            Dates3 = str(Dates3)
            Dates3 = Dates3.replace("'", "")
            Dates3 = Dates3.replace('(', '')
            Dates3 = Dates3.replace(')', '')
            Dates3 = Dates3.replace(',', '')


            crsr.execute('SELECT Text FROM Calendar2 WHERE Number = ?', (Count,))
            Text = crsr.fetchone()
            Text = str(Text)
            Text = Text.replace("'", "")
            Text = Text.replace('(', '')
            Text = Text.replace(')', '')
            Text = Text.replace(',', '')


            print(Dates3)

            Dates3 = Dates3.replace('/', ' ')
            Dates3 = Dates3.replace("'", '')
            Dates3.split()

            sqlDay = int(Dates3[0:2])
            sqlMonth = int(Dates3[3:4])
            sqlYear = int(Dates3[6:10])



            self.dates =  QDate(sqlYear, sqlMonth, sqlDay): ["Hi"]



            format = QTextCharFormat() 
            format.setBackground(QColor("lightblue")) 


            Count = Count + 1
            for date, value in self.dates.items(): 
                self.calendarWidget.setDateTextFormat(date, format)
                self.DateInfoOutput.setText(Text)
            else:
                self.DateInfoOutput.setText(Combined_Date)
        else:
            self.DateInfoOutput.setText(Combined_Date)

【问题讨论】:

要做你想做的事,你有两个步骤: 1) 使用 SQL 查询获取日期并将其转换为 QDates,根据你提供的代码,你知道如何去做。 2)由于您已经拥有 QDate,因此您可以使用 setDateTextFormat 更改每个 QDate 的背景颜色作为重复显示。 您似乎希望我们提供代码来进行复制粘贴,不幸的是,SO 不是那种类型的网站。您应该使用来自副本的信息来显示您的意图,而不是发布相同的问题。根据您的论点,如果有 2 个用户发表:如何更改周末的背景颜色?以及如何更改工作日的字体颜色?它们不一样,显然它们是一样的。 在这里,您是否花了一天或数年的时间试图解决并不重要(有一个问题多年没有得到回答)所以这个论点是无关紧要的。我从您之前的问题中看到了相同的代码,但没有努力解决您当前的问题。实际上我已经告诉过你这个过程:要更改某个日期的格式,那么你必须构建一个包含日期信息的 QDate,然后使用:format = QTextCharFormat()format.setBackground(QColor("salmon"))your_calendar.setDateTextFormat(date, format) 你设置格式的地方日期。 感谢您的回复。我知道有些问题永远不会得到回答,但我问你的每一个问题要么审查它,要么关闭它,所以我真的很生气你一直关闭它们。只是因为这是我学校的一项重要工作,我一直在强调它,因为它是我程序的主要功能,但我无法让它发挥作用。我很抱歉我的语气很傲慢,我真的很担心我不能按时完成。 对于这项任务,我们都必须创建一个程序,但使用 QT,但都在使用不同的程序,我是唯一一个尝试执行此功能的人。无论如何,我尝试使用您的代码,但我不确定该怎么做,因为。我会编辑这个问题,因为我不能把它全部放在评论中 【参考方案1】:

本案例的流程为:

对数据库进行查询。 以字符串形式获取日期。 使用指向适当格式的QDate.fromString()方法将字符串转换为QDate,并 使用QCalendarWidget.setDateTextFormat()QCalendarWidget 中设置该日期的格式。
import os
import sqlite3

from PyQt5 import QtCore, QtGui, QtWidgets

CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))

if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    calendar = QtWidgets.QCalendarWidget()
    calendar.show()

    connection = sqlite3.connect(os.path.join(CURRENT_DIR, "Calendardatabase.db"))
    crsr = connection.cursor()
    crsr.execute("""SELECT Date FROM Calendar2""")

    date_format = "d/M/yyyy"
    cell_format = QtGui.QTextCharFormat()
    cell_format.setBackground(QtGui.QColor("red"))

    for row in crsr.fetchall():
        date_str, *_ = row
        dt = QtCore.QDate.fromString(date_str, date_format)
        if dt.isValid():
            calendar.setDateTextFormat(dt, cell_format)
        else:
            print(" does not match format ".format(date_str, date_format))

    sys.exit(app.exec_())

【讨论】:

非常感谢。它终于起作用了 【参考方案2】:

在得到@eyllanesc 的帮助后,我已经完全完成了我的程序,我将把我的程序留在这里,这样如果有人遇到困难,他们可以使用我的程序作为指导,或者在任何情况下提供帮助。

    # -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Calendar.ui'
#
# Created by: PyQt5 UI code generator 5.14.1
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets
import sqlite3
import datetime
import PyQt5
from PyQt5.QtCore import QDate, Qt
from PyQt5.QtGui import (QColor, QFont, QTextCharFormat, QTextLength,
        QTextTableFormat)
from PyQt5.QtWidgets import (QApplication, QComboBox, QDateTimeEdit,
        QHBoxLayout, QLabel, QMainWindow, QSpinBox, QTextBrowser, QVBoxLayout,
        QWidget)

class Ui_CalendarWidget(object):
    def setupUi(self, CalendarWidget):
        CalendarWidget.setObjectName("CalendarWidget")
        CalendarWidget.resize(1200, 900)
        CalendarWidget.setMinimumSize(QtCore.QSize(0, 0))
        CalendarWidget.setMaximumSize(QtCore.QSize(1200, 900))
        CalendarWidget.setStyleSheet("background-color: rgb(200, 200, 200);")
        self.centralWidget = QtWidgets.QWidget(CalendarWidget)
        self.centralWidget.setObjectName("centralWidget")
        self.Header = QtWidgets.QTextEdit(self.centralWidget)
        self.Header.setEnabled(False)
        self.Header.setGeometry(QtCore.QRect(-10, 0, 1300, 110))
        self.Header.setMinimumSize(QtCore.QSize(1300, 110))
        self.Header.setMaximumSize(QtCore.QSize(1300, 110))
        self.Header.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"border-color: rgb(255, 255, 255);\n"
"border-width : 1.2px;\n"
"border-style:inset;")
        self.Header.setObjectName("Header")
        self.LECTURP = QtWidgets.QLabel(self.centralWidget)
        self.LECTURP.setGeometry(QtCore.QRect(512, 2, 180, 61))
        self.LECTURP.setStyleSheet("color: rgb(0, 176, 240);\n"
"font: 8pt \"MS Shell Dlg 2\";\n"
"text-decoration: underline;\n"
"background-color: rgb(255, 255, 255);\n"
"font: 28pt \"Calbri\";\n"
"text-decoration: underline;")
        self.LECTURP.setObjectName("LECTURP")
        self.LecturpBanner = QtWidgets.QLabel(self.centralWidget)
        self.LecturpBanner.setGeometry(QtCore.QRect(320, 60, 561, 31))
        self.LecturpBanner.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"color: rgb(0, 176, 240);\n"
"font: 14pt \"Calibri\";")
        self.LecturpBanner.setObjectName("LecturpBanner")
        self.calendarWidget = QtWidgets.QCalendarWidget(self.centralWidget)
        self.calendarWidget.setGeometry(QtCore.QRect(30, 110, 1141, 661))
        self.calendarWidget.setStyleSheet("alternate-background-color: rgb(255, 255, 255);\n"
"font: 75 16pt \"MS Shell Dlg 2\";\n"
"background-color: rgb(200, 200, 200);\n"
"selection-background-color: rgb(255, 0, 0);")
        self.calendarWidget.setObjectName("calendarWidget")
        self.DateInfoOutput = QtWidgets.QLabel(self.centralWidget)
        self.DateInfoOutput.setGeometry(QtCore.QRect(30, 778, 1141, 97))
        self.DateInfoOutput.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"border-color: rgb(0, 0, 0);\n"
"font: 16pt \"Calibri\";\n"
"border-width : 1.2px;\n"
"border-style:inset;")
        self.DateInfoOutput.setText("")
        self.DateInfoOutput.setObjectName("DateInfoOutput")
        self.WeekNumber = QtWidgets.QLabel(self.centralWidget)
        self.WeekNumber.setGeometry(QtCore.QRect(56, 168, 113, 49))
        self.WeekNumber.setStyleSheet("background-color: rgb(255, 255, 255);\n"
"font: 16pt \"MS Shell Dlg 2\";")
        self.WeekNumber.setObjectName("WeekNumber")
        self.calendarWidget.raise_()
        self.Header.raise_()
        self.LECTURP.raise_()
        self.LecturpBanner.raise_()
        self.DateInfoOutput.raise_()
        self.WeekNumber.raise_()
        CalendarWidget.setCentralWidget(self.centralWidget)
        self.statusbar = QtWidgets.QStatusBar(CalendarWidget)
        self.statusbar.setObjectName("statusbar")
        CalendarWidget.setStatusBar(self.statusbar)

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

        self.editor = QTextBrowser()


        self.calendarWidget.clicked[QDate].connect(self.dateClicked)

        connection = sqlite3.connect("Calendardatabase.db")
        crsr = connection.cursor()

        Current_Day = datetime.date.today().strftime("%A,")
        Current_Date = datetime.date.today().strftime("%d")
        Current_Month = datetime.date.today().strftime("%B")

        Combined_Date = ("It is a " + Current_Day + " It is the " + Current_Date + " of " + Current_Month)

        Combined_Date = str(Combined_Date)

        self.DateInfoOutput.setText(Combined_Date)


        #This is where the SQL Data is converted to d/M/yyyy and is then highlighted onto the calendar widget itself.

        connection = sqlite3.connect("Calendardatabase.db")
        crsr = connection.cursor()
        crsr.execute("""SELECT Date FROM Calendar2""")

        date_format = "d/M/yyyy"
        cell_format = QtGui.QTextCharFormat()
        cell_format.setBackground(QtGui.QColor("lightblue"))

        for row in crsr.fetchall():
            date_str, *_ = row
            dt = QtCore.QDate.fromString(date_str, date_format)
            if dt.isValid():
                self.calendarWidget.setDateTextFormat(dt, cell_format)
            else:
                self.DateInfoOutput.setText(" does not match format ".format(date_str, date_format))









    def dateClicked(self, clickedDate):
        connection = sqlite3.connect("Calendardatabase.db") 
        # This is the code for the database cursor 
        crsr = connection.cursor() 
        Count = 1
        crsr.execute('SELECT Day FROM Calendar WHERE Number = ?', (Count,))
        RawDay = crsr.fetchone()
        Day = str(RawDay)
        Day = Day.replace('(', '')
        Day = Day.replace(')', '')
        Day = Day.replace(',', '')
        Day = int(Day)

        crsr.execute('SELECT Month FROM Calendar WHERE Number = ?', (Count,))
        RawMonth = crsr.fetchone()
        Month = str(RawMonth)
        Month = Month.replace('(', '')
        Month = Month.replace(')', '')
        Month = Month.replace(',', '')
        Month = int(Month)

        crsr.execute('SELECT Year FROM Calendar WHERE Number = ?', (Count,))
        RawYear = crsr.fetchone()
        Year = str(RawDay)
        Year = Year.replace('(', '')
        Year = Year.replace(')', '')
        Year = Year.replace(',', '')
        Year = int(Year)        


        Current_Day = datetime.date.today().strftime("%A,")
        Current_Date = datetime.date.today().strftime("%d")
        Current_Month = datetime.date.today().strftime("%B")


        Combined_Date = ("It is a " + Current_Day + " It is the " + Current_Date + " of " + Current_Month)

        Combined_Date = str(Combined_Date)

        self.DateInfoOutput.setText(Combined_Date)

        cursor = self.editor.textCursor()

        All_Dates = (Day, Month, Year)

        self.selectedDate = QDate.currentDate()
        connection = sqlite3.connect("Calendardatabase.db") 
        crsr = connection.cursor() 
        crsr.execute(
            'SELECT Text FROM Calendar WHERE Day = ? AND Month = ? AND YEAR = ?', 
            (clickedDate.day(), clickedDate.month(), clickedDate.year()))
        result = crsr.fetchone()

        self.Date = (clickedDate.day() , '/' , clickedDate.month() , '/' , clickedDate.year())



        if result:
            self.DateInfoOutput.setText(result[0])


        else:
            self.DateInfoOutput.setText(Combined_Date)








    def retranslateUi(self, CalendarWidget):
        _translate = QtCore.QCoreApplication.translate
        CalendarWidget.setWindowTitle(_translate("CalendarWidget", "CalendarWidget"))
        self.LECTURP.setText(_translate("CalendarWidget", "LECTURP"))
        self.LecturpBanner.setText(_translate("CalendarWidget", "Lecture, Exam, Coursework, Timetable, Uploader and Reminder Program."))
        self.WeekNumber.setText(_translate("CalendarWidget", "Week No."))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    CalendarWidget = QtWidgets.QMainWindow()
    ui = Ui_CalendarWidget()
    ui.setupUi(CalendarWidget)
    CalendarWidget.show()
    sys.exit(app.exec_())

要让这个程序正常工作,你还需要我的数据库,你可以从这里得到它: https://www.dropbox.com/s/cua9gypkl869hnm/Calendardatabase.db?dl=0 如果你只是把它和程序文件放在同一个文件夹中,这应该可以工作。

感谢@eyllanesc 的所有帮助,如果没有你的帮助,我会在这个问题上被困几个星期:)

【讨论】:

以上是关于如何使用 SQL 数据库更改 QCalendarWidget 中单元格的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 c# 监控 SQL Server 表更改?

SQL 数据更改时触发脚本

如何使用 sql 查询更改“sa”的密码? [关闭]

如何从 SQL Express 2012 获取数据更改通知?

如何更改实体框架项目以使用 Microsoft SQL Server

计算机名称更改后,软件无法连接SQL数据库!急求!