使用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_QMainWindow
class CMapEdit : public QMainWindow
#else
class CMapEdit : public QWidget
#endif
{
Q_OBJECT
public:
CMapEdit(QWidget *parent = nullptr);
~CMapEdit();
void paintEvent(QPaintEvent *);
public:
static int m_iCount;
#ifdef USE_QMainWindow
Ui::MapEditUi_MainWindow *ui = nullptr;
#else
Ui::MapEditUi_Widget *ui = nullptr;
#endif
};
#endif // CMAPEDIT_H
cmapedit.cpp
#include "cmapedit.h"
#include <QDebug>
int CMapEdit::m_iCount = 1;
#ifdef inherit_QMainWindow
CMapEdit::CMapEdit(QWidget *parent): QMainWindow(parent)
#else
CMapEdit::CMapEdit(QWidget *parent): QWidget(parent)
# endif
{
#ifdef USE_QMainWindow
ui = new Ui::MapEditUi_MainWindow;
#else
ui = new Ui::MapEditUi_Widget;
# endif
ui->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