使用Qt 的时候发现:
- 背景:自己定义一个类,把它和某个ui文件绑定。(类似 Qt creator 默认创建的工程)
- 问题:当鼠标在窗口内单击的时候会触发2次绘图。?难道不应该是一次吗?
于是开始了如下的测试:
- 创建 qt creator 默认带有ui的工程。
- 重写 paintevent 虚函数,利用静态变量实现计数
简述主要实验结果:
- 如果不使用 ui 文件,那都是刷新一次,正常。
- 如果使用 ui 文件,仅仅组合:(主窗口QWidget + Ui类QWidget 是正常的刷新一次,其他的都是两次)。
请问有高手知道这是怎么回事吗?
代码
我的代码有5个文件
- cmapedit.h
- cmapedit.cpp
- main.cpp 没有任何修改
- MapEditUi_MainWindow.ui 没有任何修改
- MapEditUi_Widget.ui 没有任何修改
cmapedit.h
/*** @brief 自定义主窗口类* @details 仅修改 paintEvent,通过宏定义实现动态编译* @mainpage* @date 2023-10-24*/#ifndef CMAPEDIT_H
#define CMAPEDIT_H#include <QWidget>
#include <QMainWindow>
#include "ui_MapEditUi_MainWindow.h"
#include "ui_MapEditUi_Widget.h"#define inherit_QMainWindow // 宏定义:继承自 QMainWindow 还是 QWidget
#define USE_QMainWindow // 宏定义:ui类是 QMainWindow 还是 QWidget#ifdef inherit_QMainWindowclass CMapEdit : public QMainWindow
#elseclass CMapEdit : public QWidget
#endif
{Q_OBJECTpublic:CMapEdit(QWidget *parent = nullptr);~CMapEdit();void paintEvent(QPaintEvent *);public:static int m_iCount;#ifdef USE_QMainWindowUi::MapEditUi_MainWindow *ui = nullptr;#elseUi::MapEditUi_Widget *ui = nullptr;#endif
};
#endif // CMAPEDIT_H
cmapedit.cpp
#include "cmapedit.h"
#include <QDebug>int CMapEdit::m_iCount = 1;#ifdef inherit_QMainWindowCMapEdit::CMapEdit(QWidget *parent): QMainWindow(parent)
#elseCMapEdit::CMapEdit(QWidget *parent): QWidget(parent)
# endif
{#ifdef USE_QMainWindowui = new Ui::MapEditUi_MainWindow;#elseui = new Ui::MapEditUi_Widget;# endifui->setupUi(this);
}CMapEdit::~CMapEdit(){}void CMapEdit::paintEvent(QPaintEvent * event)
{qDebug()<< "paint" << m_iCount++;
}
测试1:
重载mousePressEvent和mouseReleaseEvent 事件,观察这两个事件和paintEvent的先后顺序。
测试结果:
- 在界面上不断单击,不会触发绘图。
- 先单击桌面,再单击窗口内部:事件顺序:
- Pressevent
- 绘图1
- 绘图2 (任然是触发2次)
- Releaseevent
最终总结
在经过多次实验后发现:如果你的鼠标在应用和桌面来回点击切换(不是在只应用中点),则:
- 其实和主类别所继承的类型、ui的类型以及是否使用手写都无关
- 在Qt creator 的默认项目,如果页面上没有任何东西,则主页面的调用次数为1
- 如果页面上有任何控件,无论控件数量的多少,都为2