带有自定义QCalendarWidget的QDateTimeEdit拦截鼠标点击?

时间:2015-10-09 04:34:01

标签: qt pyside

根据PySide docs

  

QDateTimeEdit可以配置为允许QCalendarWidget用于选择日期。通过设置QDateTimeEdit.calendarPopup()属性启用此功能。此外,您可以通过调用QDateTimeEdit.setCalendarWidget()函数提供自定义日历窗口小部件,以用作日历弹出窗口。可以使用QDateTimeEdit.calendarWidget()检索现有的日历窗口小部件。

很酷,我可以这样做,但我的问题是它的用途是什么?自定义日历小部件似乎不能拦截鼠标点击或绘制事件,这在我看来是您想要使用自定义日历小部件做的事情。无论如何,这就是我想要做的。我写了一个快速的脚本来测试它:

from PySide.QtGui import *
from PySide.QtCore import *

import sys 

class EventLogger(QObject):
    def __init__(self, **kwargs):
        super(EventLogger, self).__init__(**kwargs)

    def eventFilter(self, obj, event):
        print "Object = %s; event = %s" % (type(obj).__name__, event.type())
        return False

class MyCalendar(QCalendarWidget):
    def __init__(self, **kwargs):
        super(MyCalendar, self).__init__(**kwargs)
        self.installEventFilter(EventLogger(parent=self))
        print "*** Initializing custom calendar widget ***"

    def mousePressEvent(self, e): 
        print "*** Intercepting mouse press event ***"

class MyWidget(QWidget):
    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        self._initUI()

        self.show()
        self.setFocus()
        self.raise_()

    def _initUI(self):
        layout = QGridLayout()
        self.setLayout(layout)

        de = QDateTimeEdit()
        de.setCalendarPopup(True)
        de.setCalendarWidget(MyCalendar(parent=de))
        layout.addWidget(de, 0, 0, 1, 1)

def main():
    app = QApplication([])
    mw = MyWidget()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

运行此程序,打开日历,单击日期,然后退出程序输出:

*** Initializing custom calendar widget *** 
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.ParentChange
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Polish
Object = MyCalendar; event = PySide.QtCore.QEvent.Type(70)
Object = MyCalendar; event = PySide.QtCore.QEvent.Type(70)
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.ChildPolished
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.ChildPolished
Object = MyCalendar; event = PySide.QtCore.QEvent.Type(67)
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.PolishRequest
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.LayoutRequest
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Move
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Resize
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Show
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.ShowToParent
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.LayoutRequest
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Enter
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Hide
Object = MyCalendar; event = PySide.QtCore.QEvent.Type.Leave
Object = QWidget; event = PySide.QtCore.QEvent.Type.DynamicPropertyChange
Object = QWidget; event = PySide.QtCore.QEvent.Type.ChildRemoved

这是因为缺少鼠标点击和绘制事件而引起注意,并且mousePressEvent()函数未被调用。那么真正定制这个最简单的方法是什么?我是否必须自己重新实施QDateTimeEdit / QCalendarWidget?文档说你可以自定义日历,但不提供任何有关如何正确执行日程的细节,甚至不提供你想要的原因,因为它在这种情况下显然有限。

1 个答案:

答案 0 :(得分:0)

好的,要回答我自己的问题,通过拦截鼠标点击和绘制事件,使用paintCell()方法和clicked,正确的方法是 not 信号,根据tmoreau的评论。我想,这有点违反直觉,但是paintCell()方法为你提供了每天的矩形,这很方便。