Выбор даты в QCalendarWidget правой кнопкой мыши с одновременным выводом контекстного меню
Не могу решить вопрос с выбором даты в календаре правой кнопкой мыши.
Когда пользователь наводить курсор на определенную дату, нажимает правую кнопку мыши, то дата выделяется и появляется контекстное меню.
Предполагаю, что нужно переопределить метод mousePressEvent()
, но не могу понять, как это сделать?
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QCalendarWidget, QMenu, QAction
class MyCalendar(QCalendarWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setVerticalHeaderFormat(QCalendarWidget.NoVerticalHeader)
self.setCursor(Qt.PointingHandCursor)
def contextMenuEvent(self, event):
menu_for_cal = QMenu()
menu_for_cal.addAction(QAction('First_action', self))
menu_for_cal.addAction(QAction('Second_action', self))
menu_for_cal.exec(event.globalPos())
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
print("Left Button Clicked")
elif event.button() == Qt.RightButton:
print("Right Button Clicked")
class MyWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Координаты и события")
self.resize(300, 200)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.layout = QVBoxLayout()
self.centralWidget.setLayout(self.layout)
self.cal = MyCalendar(self)
self.layout.addWidget(self.cal, alignment=Qt.AlignCenter)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
Ответы (2 шт):
Предполагаете правильно. Для начала, стоит посмотреть как работает стандартная реализация. Если при клике ПКМ, дата выделяется, то достаточно вызвать оригинальный метод, а на условие (как у вас уже сделано), необходимо вызывать QMenu
в позиции клика мыши.
PS: сперва не обратил внимание на ваш метод для вызова меню. В таком случае, вы можете вызывать непосредственно его, разве что у методов разные Event
ы передаются
Как вариант
import sys
from PyQt5.QtCore import Qt, QPoint, QModelIndex, QDate
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, \
QCalendarWidget, QMenu, QAction, QApplication, QTableView
class MyCalendar(QCalendarWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setVerticalHeaderFormat(QCalendarWidget.NoVerticalHeader)
self.setCursor(Qt.PointingHandCursor)
# +++
self.press_date = QDate() # +++
def contextMenuEvent(self, event):
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
childrens = self.children() # +++
for ch in childrens:
if isinstance(ch, QTableView):
index = ch.indexAt(event.pos() - QPoint(0, 20))
day = ch.model().data(index)
self.press_date = QDate(
self.yearShown(), self.monthShown(), day)
print(self.press_date) #
self.setSelectedDate(self.press_date)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
menu_for_cal = QMenu()
menu_for_cal.addAction(QAction('First_action', self))
menu_for_cal.addAction(QAction('Second_action', self))
menu_for_cal.exec(event.globalPos())
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def paintCell(self, painter, rect, date):
painter.setRenderHint(QPainter.Antialiasing, True)
super().paintCell(painter, rect, date)
if date == self.press_date:
painter.setBrush(QColor(122, 27, 181, 50))
painter.drawRect(rect)
painter.setBrush(Qt.red)
painter.drawEllipse(rect.topLeft() + QPoint(5, 5 ), 3, 3)
else:
QCalendarWidget.paintCell(self, painter, rect, date)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.cal = MyCalendar(self)
self.layout = QVBoxLayout(self.centralWidget)
self.layout.addWidget(self.cal, alignment=Qt.AlignCenter)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyWindow()
window.setWindowTitle("Координаты и события")
window.resize(300, 200)
window.show()
sys.exit(app.exec_())