在项目中遇到Linux环境重Dialog在双击标题栏时对话框会最大化的情况,
在设置MaxmiumSize等都没有效果的情况下所以自设标题栏。
大体思路是通过三个空间组成标题栏的图标、标题、关闭按键,
并且通过鼠标事件来控制框体的移动。
通过继承QDialog,将标题栏和将所要显示的内容的Widget组合起来,
通过GetCurChildWidget()接口将Widget接口暴露出来供后续填充自己想要的Widget,
这样便可以将项目中需要使用Dialog的部件统一风格。
// TitileBar.h
#ifndef __TITLEBAR_H_
#define __TITLEBAR_H_
#include <QDialog>
class QEvent;
class QMouseEvent;
class QPixmap;
class QColor;
class QLabel;
class QPushButton;
class QPoint;
class QString;
class TitleBar : public QWidget
{
Q_OBJECT
Q_PROPERTY(QColor TitleColor READ getTitleColor WRITE setTitleColor )
public:
TitleBar(QWidget* parent = 0,Qt::WindowFlags f = 0);
~TitleBar();
void SetWindowTitle(QString& strTitle);
void SetWindowIcon(QPixmap& pixTitle);
QColor getTitleColor();
void setTitleColor(QColor& col);
protected:
void mousePressEvent(QMouseEvent* event); /// 重写鼠标按压事件
void mouseMoveEvent(QMouseEvent* event); /// 重写鼠标移动事件
void mouseReleaseEvent(QMouseEvent* event); /// 重新鼠标释放事件
private:
bool isLeftMousePressed;
QString strTypeface;
int32_t ulScreenWidht;
QPoint HistoryPos;
QLabel* WindowTitleLab;
QLabel* TitleIconLab;
QPushButton* CloseBtn;
QColor TitleColor;
signals:
void CloseBtnClickEvent();
private slots:
void on_CloseBtn_Pressed();
};
#endif //TitleBar.h
// TitleBar.cpp
#include "TitleBar.h"
#include <QMouseEvent>
#include <QPixmap>
#include <QColor>
#include <QLabel>
#include <QPushButton>
#include <QPoint>
#include <QString>
#include "CStaticDatas.h" // 主要是获取控件分辨率的一些函数
TitleBar::TitleBar(QWidget* parent,Qt::WindowFlags flags)
:isLeftMousePressed(false)
{
CStaticDatas *cStaticDatas = CStaticDatas::getCStaticDatasInstance();
strTypeface = cStaticDatas->getFont();
ulScreenWidht = cStaticDatas->getScreenWidth(); /// 获取分辨率
HistoryPos.setX(0);
HistoryPos.setY(0);
setWindowFlags(Qt::FramelessWindowHint);
TitleIconLab = new QLabel(this);
TitleIconLab->setObjectName("TitleIconLab");
TitleIconLab->setFixedSize(20,20);
QPixmap pix;
pix.load(":/SubIcon/SbuIcon/unitteclogo.png");
TitleIconLab->setPixmap(pix);
TitleIconLab->setScaledContents(true);
TitleIconLab->setStyleSheet("QLabel#TitleIconLab{border:0px;};");
WindowTitleLab = new QLabel(this);
WindowTitleLab->setObjectName("WindowTitleLab");
WindowTitleLab->setPixmap(QPixmap(20,20));
WindowTitleLab->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
QString strWindowTitle = "QLabel#WindowTitleLab{border:0px;font-size:" + QString::number(ulScreenWidht / 68) \
+ "px;font-family:" + strTypeface + "; };";
WindowTitleLab->setStyleSheet(strWindowTitle);
CloseBtn = new QPushButton(this);
CloseBtn->setIcon(QIcon(":/SubIcon/SbuIcon/Close.png"));
CloseBtn->setFixedSize(20,20);
CloseBtn->setObjectName("CloseBtn");
CloseBtn->setStyleSheet("QPushButton#CloseBtn{border:0px;}");
QHBoxLayout* TitleLayout = new QHBoxLayout;
TitleLayout->addWidget(TitleIconLab,0,Qt::AlignLeft);
TitleLayout->addWidget(WindowTitleLab,0,Qt::AlignCenter);
TitleLayout->addWidget(CloseBtn,0,Qt::AlignRight);
TitleLayout->setContentsMargins(2,0,2,0);
connect(CloseBtn,SIGNAL(clicked()),this,SLOT(on_CloseBtn_Pressed()));
setLayout(TitleLayout);
}
TitleBar::~TitleBar()
{
}
void TitleBar::SetWindowTitle(QString& strTitle)
{
WindowTitleLab->setText(strTitle);
}
void TitleBar::SetWindowIcon(QPixmap& pixTitle)
{
TitleIconLab->setPixmap(pixTitle);
}
void TitleBar::mousePressEvent(QMouseEvent*event)
{
if(event->button() == Qt::LeftButton)
{
HistoryPos = event->globalPos();
isLeftMousePressed = true;
}
}
void TitleBar::mouseMoveEvent(QMouseEvent* event)
{
if(isLeftMousePressed == true)
{
parentWidget()->move(parentWidget()->geometry().topLeft() \
+ event->globalPos() - HistoryPos);
HistoryPos = event->globalPos();
}
}
void TitleBar::mouseReleaseEvent(QMouseEvent* event)
{
if(event->button() == Qt::LeftButton)
{
isLeftMousePressed = false;
}
}
void TitleBar::on_CloseBtn_Pressed()
{
emit CloseBtnClickEvent();
}
QColor TitleBar::getTitleColor()
{
return palette().window().color();
}
void TitleBar::setTitleColor(QColor& col)
{
QPalette pale = palette();
pale.setColor(QPalette::Background, col);
setAutoFillBackground(true);
setPalette(pale);
}
// Dis_Dialog.h
#ifndef _DIS_DIALOG_H__
#define _DIS_DIALOG_H__
#include <QDialog>
#include <QColor>
#include "TitleBar.h"
class QWidget;
class QVBoxLayout;
class dialog : public QDialog
{
Q_OBJECT
public:
dialog(QWidget *parent = 0, Qt::WFlags flags = 0);
~dialog();
void SetWindowTitle(QString& title); /// 设置标题栏文字
void SetWindowIcon(QPixmap& pixTitle); /// 设置标题栏图标
QColor GetTitleColor(); /// 获取标题栏背景色
bool SetTitleColor(QColor& col); /// 设置标题栏背景色
QWidget* GetCurChildWidget(); /// 获取当前对话框的内容栏,共外部组件使用
void SetDlgLayoutStretch(int,int); /// 设置标题栏和内容框比例 一般2:9就够用了,可以调
private:
QWidget* widget;
TitleBar* titleBar;
QVBoxLayout* MainLayout;
};
#endif //DIS_Dialog.h
// Dis_Dialog.cpp
#include <QWidget>
#include <QEvent>
#include <QLabel>
#include <QMouseEvent>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
/// 对话框构造函数
dialog::dialog(QWidget *parent, Qt::WFlags flags)
{
setWindowFlags(Qt::FramelessWindowHint);
titleBar = new TitleBar;
QColor TitleColor(255,193,37);
titleBar->setProperty("TitleColor",TitleColor);
widget = new QWidget();
widget->setObjectName("widget");
MainLayout = new QVBoxLayout();
MainLayout->addWidget(titleBar);
MainLayout->addWidget(widget);
SetDlgLayoutStretch(2,9);
MainLayout->setContentsMargins(2,0,2,2);
MainLayout->setSpacing(0);
connect(titleBar,SIGNAL(CloseBtnClickEvent()),this,SLOT(close()));
//setFixedSize(600,400);
setLayout(MainLayout);
}
dialog::~dialog()
{
}
/// 设置标题栏的文字
void dialog::SetWindowTitle(QString& title)
{
titleBar->SetWindowTitle(title);
}
/// 设置标题栏的图标
void dialog::SetWindowIcon(QPixmap& pixTitle)
{
titleBar->SetWindowIcon(pixTitle);
}
/// 返回对话框的widget
QWidget* dialog::GetCurChildWidget()
{
return widget;
}
/// 获取标题栏颜色
QColor dialog::GetTitleColor()
{
return titleBar->property("TitleColor").value<QColor>();
}
/// 设置标题栏颜色
bool dialog::SetTitleColor(QColor& col)
{
return titleBar->setProperty("TitleColor",QVariant(col));
}
void dialog::SetDlgLayoutStretch(int TitleBarFactor,int ContentFactor)
{
MainLayout->setStretch(0,TitleBarFactor);
MainLayout->setStretch(1,ContentFactor);
}
最后,代码和思路上参考如下博文:
https://blog.51cto.com/9291927/2330380