如何使用 C++ 继承和扩展 QCalendarWidget

发布于 2024-09-12 14:59:25 字数 414 浏览 2 评论 0原文

目前QCalendarWidget仅支持SingleSelection或NoSelection。我希望能够编写一个继承自 Qt 4.6.2 中的 QCalendarWidget 的小部件,并添加用户选择一周中任意一天并选择自定义周的功能。

例如,单击 2010 年 8 月 5 日星期四,然后选择从 7 月 31 日星期六到 8 月 6 日星期五(含)的所有日期。

我对 Qt 的经验有限,而且我已经有一段时间没有接触过 C++ 了,所以我是否需要担心在 Qt 中继承时实现复制构造函数或虚拟析构函数,或者需要注意的任何其他陷阱?对于这样的自定义小部件,头文件和 cpp 文件会是什么样子?添加自定义绘制逻辑和 SelectionMode 的最佳位置在哪里?

我正在使用 gcc 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5) 和 Qt 4.6.2

At present the QCalendarWidget only supports SingleSelection or NoSelection. I'd like to be able to write a widget that inherits from QCalendarWidget in Qt 4.6.2 and adds the ability for the user to select any day in a week and have that custom week selected.

e.g. Click on Thu 5 August 2010 and all days from Saturday 31 July to Friday 6 August inclusive get selected.

My experience with Qt is limited and it's been a while since I've done some C++ so do I need to worry about implementing a copy constructor or virtual destructors when inheriting in Qt, or any other pitfalls to be aware of? What would the header and cpp files look like for such a custom widget and where is the best place to add my custom paint logic and SelectionMode?

I'm using gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) and Qt 4.6.2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

掀纱窥君容 2024-09-19 14:59:25

阅读 QCalendarWidget 源代码后,在我看来这可能是继承的情况,但是会有问题。

首先,从 QObject 派生的类(包括小部件)不应具有复制构造函数。对此的解释在这里。 QObject 析构函数是虚拟的,因此无论您如何声明,

当扩展一个类来改变它的行为时,寻找虚函数。如果没有,则很好地表明继承可能不是最好的方法。在本例中,我们有三个虚拟方法:

virtual QSize sizeHint() const;
virtual QSize minimumSizeHint() const;
virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;

前两个是来自 QWidget 的虚拟方法,用于调整小部件的大小。它们可能并不重要。最后一个可能会完成您想要的部分操作:当用户选择一周中的某一天时,使整周显示为已选择。

现在,对于可能的问题:

选择模式属性是非虚拟的,而且是枚举值的。无法扩展枚举类型以包含新建议的 WeekSelection 值。如果您不必在运行时更改选择模式,则可以安全地忽略此属性并仅使用周选择。 (忽略属性很好地表明您的小部件可能应该拥有 QCalendarView,而不是成为 QCalendarView。)

QCalendarView 也是一个复合小部件(与标签或按钮不同 ) )。内部由一个QTableView、许多QToolButton、一个QSpinBox等组成。这种小部件很难通过继承进行扩展,因为您无法访问其内部结构,并且大多数行为(例如绘制和处理输入事件)是由内部小部件完成的,而不是由 QCalendarView 本身完成的。

在某些情况下,您可以使用 findChildren() 寻找子窗口小部件,并通过更改属性和 安装事件过滤器。然而,这很容易被破坏,因为只要保留类的公共二进制接口,诺基亚就可以将内部结构从 4.6.2 更改为 4.6.3。

问问自己新的小部件是否必须继承自 QCalendarWidget。如果不是,并且继承会导致您陷入死胡同,请考虑复制 QCalendarWidget 的源代码并根据您的需要进行调整。您可以更进一步克隆 Qt 源代码,更改原始小部件本身以包含您的行为并向诺基亚提出合并请求。

After reading the QCalendarWidget source code, it seems to me this might be the case for inheritance, but there will be issues.

First, classes that derive from QObject, widgets included, shouldn’t have copy constructors. The explanation for this is here. The QObject destructor is virtual, so no matter how you declare yours, it will be virtual too.

When extending a class to change its behavior, look for virtual functions. If there aren’t any, it’s a good indication that inheritance might not be the best approach. In this case, we have three virtual methods:

virtual QSize sizeHint() const;
virtual QSize minimumSizeHint() const;
virtual void paintCell(QPainter *painter, const QRect &rect, const QDate &date) const;

The first two are virtuals from QWidget and deal with sizing the widget. They are probably not important. The last one might do part of what you want: making the whole week appear selected when a day of that week is picked by the user.

Now, for the possible issues:

The selection mode property is non-virtual and, moreover, is enum-valued. One cannot extend the enumerated type to include the new proposed WeekSelection value. If you don’t have to change selection modes on runtime, you can safely ignore this property and work only with week selections. (Ignoring a property is a good indication that your widget should probably have a QCalendarView and not be a QCalendarView.)

QCalendarView is also a composite widget (unlike a label or push button). Internally, it is made of a QTableView, many QToolButtons, a QSpinBox and so on. This kind of widget is harder to extend by inheritance, because you don’t have access to its internals and most of the behavior (such as painting and handling input events) is done by the internal widgets, not by QCalendarView itself.

In some situations, you can hunt for the children widgets using findChildren() and modify their behavior by changing properties and installing event filters. This is prone to break, however, because Nokia can change the internals from 4.6.2 to 4.6.3 as long as the public binary interface of the class is preserved.

Ask yourself if the new widget must inherit from QCalendarWidget. If not and inheriting leads you to a dead end, consider copying the source code of QCalendarWidget and adapting it to your needs. You can go even further and clone the Qt source code, change the original widget itself to include your behavior and propose a merge request back to Nokia.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文