Как выделить даты в PyQt5 на calendarWidget с помощью клика мыши, и чтобы выделенная дата при клике второй раз на него убирало выделение
Я стараюсь сделать программу на PyQt5, где можно выбрать даты в calendarWidget, с помощью клика мышки по дате в произвольном порядке.
Эти даты как-нибудь выделились (другой цвет шрифта, выделить рамкой). В моем случае, это маленький кружок сверх слева.
Но у меня не получается сделать так, чтобы после выделения второй клик по той же дате, убирал выделение.
Как выделить дату мне уже подсказали здесь же, но я не могу понять, как работает сигнал клика по дате, и метод paintCell.
Вот код, который просто выделяет даты.
введите сюда код
from PyQt5.QtWidgets import QCalendarWidget, QApplication
from PyQt5.QtCore import QDate, QPoint, Qt
import sys
class Scheduler(QCalendarWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.events = list()
self.clicked['QDate'].connect(self.show_date_func)
def paintCell(self, painter, rect, date):
super().paintCell(painter, rect, date)
if date in self.events:
painter.setBrush(Qt.red)
painter.drawEllipse(rect.topLeft() + QPoint(12, 7), 3, 3)
def show_date_func(self, date):
self.events.append(date)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Scheduler()
w.show()
sys.exit(app.exec_())
Я пытался решить задачу таким образом: добавить в paintCell цикл, который проверяет повторяющиеся значения в self.events, вычисляет их, и если значение делится на 2 без остатков, то срабатывает обычный конструктор который закрашивает по умолчанию. Но он не работает потому, что клик по уже закрашенной дате не выполняется.
Ответы (1 шт):
Вы дату, по которой кликнули, сохраняете в список self.events.
Удалите ее из списка если она там уже есть.
import sys
from PyQt5.QtWidgets import QCalendarWidget, QApplication
from PyQt5.QtCore import QDate, QPoint, Qt
class Scheduler(QCalendarWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.events = list()
self.clicked['QDate'].connect(self.show_date_func)
def paintCell(self, painter, rect, date):
super().paintCell(painter, rect, date)
if date in self.events:
painter.setBrush(Qt.red)
painter.drawEllipse(rect.topLeft() + QPoint(12, 7), 3, 3)
def show_date_func(self, date):
if date in self.events: # +++
index = self.events.index(date) # +++
self.events.pop(index) # +++
else: # +++
self.events.append(date)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = Scheduler()
w.show()
sys.exit(app.exec_())
Update
Да этот вариант рабочий, но это работает как-то коряво. Сначала выбираю дату (дата отмечается) кликаю второй раз по этой же дате, отметка даты не убирается, потом выбираю другую дату, потом кликаю на отмеченную дату и только потом отметка даты убирается. Разве нет другого способа?
Да, все можно решить.
import sys
from PyQt5.QtWidgets import QCalendarWidget, QApplication, \
QMainWindow, QWidget, QVBoxLayout, QLabel
from PyQt5.QtCore import QDate, QPoint, Qt
class Scheduler(QCalendarWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent # +++ parent
def paintCell(self, painter, rect, date):
super().paintCell(painter, rect, date)
if date in self.parent.events: # +++ parent
painter.setBrush(Qt.red)
painter.drawEllipse(rect.topLeft() + QPoint(12, 7), 3, 3)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.events = list()
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.scheduler = Scheduler(self) # +++ self
self.scheduler.clicked['QDate'].connect(self.show_date_func)
self.label = QLabel()
layout = QVBoxLayout(self.centralWidget)
layout.addWidget(self.scheduler)
layout.addWidget(self.label)
def show_date_func(self, date):
if date in self.events:
index = self.events.index(date)
self.events.pop(index)
else:
self.events.append(date)
self.label.setFocus() # +++
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())


