工作项目中,利用到Qt对话框,场景需求:
1. 一部分窗体需要继承自QWidget
2. 一部分窗体需要继承自QDialog
3. 两者均需要去掉标题栏图标,同时能够*拖动。
如果两者分开继承实现,会造成设置windowFlags、拖动功能部分代码重复冗余,为了达到代码复用的目的,利用模板类进行了封装。
本地使用效果正常,特此备录。
【1】头文件
#ifndef _UPC_DIALOG_BASE_H
#define _UPC_DIALOG_BASE_H #include <QDialog>
#include <QWidget>
#include <QPoint>
#include <QMouseEvent> template <typename T>
class UPCBaseWidget : public T
{
public:
UPCBaseWidget(QWidget *parent = Q_NULLPTR);
virtual ~UPCBaseWidget(); virtual int initialze() = ; protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event); private:
bool m_bMoving; // 移动标志
QPoint m_pointPosition; // 移动位置
}; /**
* @brief: 窗体基类。主要用于统一窗体风格和操作
* @author: Liuy
*/ class UPCCommonWidget : public UPCBaseWidget<QWidget>
{
Q_OBJECT public:
UPCCommonWidget(QWidget *parent = Q_NULLPTR);
~UPCCommonWidget();
}; /**
* @brief: 对话框基类。主要用于统一对话框风格和操作
* @author: Liuy
*/
class UPCCommonDialog : public UPCBaseWidget<QDialog>
{
Q_OBJECT public:
UPCCommonDialog(QWidget *parent = Q_NULLPTR);
~UPCCommonDialog();
}; #endif
【2】实现文件
#include "UPCDialogBase.h"
#include "UPCSoftphoneConst.h" #include <QIcon>
#include <QApplication> /*
* @brief: 构造函数
* @argument: QWidget * parent
*/
template <typename T>
UPCBaseWidget<T>::UPCBaseWidget(QWidget *parent)
: T(parent)
, m_bMoving(false)
{
// 设置系统图标
setWindowIcon(QIcon(SYSTEM_ICON));
// 设置关闭摧毁
setAttribute(Qt::WA_DeleteOnClose);
// 设置窗体背景为白色
QPalette palette;
palette.setColor(QPalette::Background, Qt::white);
setPalette(palette); // 为了解决弹窗关闭后整个应用程序退出问题
QApplication::setQuitOnLastWindowClosed(false);
} template <typename T>
UPCBaseWidget<T>::~UPCBaseWidget()
{} /*
* @brief: 重写鼠标按下事件处理过程
* @argument: QMouseEvent * event
* @return:void
*/
template <typename T>
void UPCBaseWidget<T>::mousePressEvent(QMouseEvent *event)
{
m_bMoving = true;
// 记录下鼠标相对于窗口的位置
// event->globalPos() 鼠标按下时,鼠标相对于整个屏幕位置
// pos() 即:this->pos() 鼠标按下时,窗口相对于整个屏幕位置
m_pointPosition = event->globalPos() - pos();
return T::mousePressEvent(event);
} /*
* @brief: 重写鼠标移动事件处理过程
* @argument: QMouseEvent * event
* @return:void
*/
template <typename T>
void UPCBaseWidget<T>::mouseMoveEvent(QMouseEvent *event)
{
// (event->buttons() && Qt::LeftButton)按下是左键
// 鼠标移动事件需要移动窗口,窗口移动到哪里呢?就是要获取鼠标移动中,窗口在整个屏幕的坐标,然后move到这个坐标,怎么获取坐标?
// 通过事件event->globalPos()知道鼠标坐标,鼠标坐标减去鼠标相对于窗口位置,就是窗口在整个屏幕的坐标
if (m_bMoving &&
(event->buttons() && Qt::LeftButton) &&
(event->globalPos() - m_pointPosition).manhattanLength() > QApplication::startDragDistance())
{
move(event->globalPos() - m_pointPosition);
m_pointPosition = event->globalPos() - pos();
} return T::mouseMoveEvent(event);
} /*
* @brief: 重写鼠标释放事件处理过程
* @argument: QMouseEvent * event
* @return:void
*/
template <typename T>
void UPCBaseWidget<T>::mouseReleaseEvent(QMouseEvent *event)
{
m_bMoving = false;
return T::mouseReleaseEvent(event);
} /*
* @brief: 构造函数
* @argument: QWidget * parent
*/
UPCCommonWidget::UPCCommonWidget(QWidget *parent)
: UPCBaseWidget<QWidget>(parent)
{
// 去掉任务栏图标 && 去掉标题栏 && 最上层显示
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowStaysOnTopHint);
} UPCCommonWidget::~UPCCommonWidget()
{} /*
* @brief: 构造函数
* @argument: QWidget * parent
*/
UPCCommonDialog::UPCCommonDialog(QWidget *parent)
: UPCBaseWidget<QDialog>(parent)
{
// 去掉标题栏 && 最上层显示
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinimizeButtonHint | Qt::WindowStaysOnTopHint);
} UPCCommonDialog::~UPCCommonDialog()
{}
Good Good Study, Day Day Up.
顺序 选择 循环 总结