实现思路:新建类MyWidget,继承Widget。
新建两个widget,titilewidget、centerwidget分别用于放置标题栏和其他内容。
在titlewidget里边添加图标、标题、最小化、最大化、关闭按钮
........
效果:
MyWidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#pragma execution_character_set("UTF-8")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
class MyWidget: public QWidget
{
Q_OBJECT
private:
QWidget *titleWidget;//标题栏Widget
QToolButton *iconButton;//图标
QPushButton *closeButton;//关闭按钮
QPushButton *maxButton;//最大化按钮
QPushButton *minButton;//最小化按钮
QLabel *titleLabel;//标题label
QRect winRect;//窗口位置
bool m_ismaxed;//窗口是否最大化
QPoint m_leftDownp;//左键按下的位置
QPoint m_leftDownMapp;//左键按下时全局位置
bool m_isleftClicked;//左键是否按下
enum
{
Left,
Right,
Up,
Bottom,
LeftUp,
RightUp,
LeftBottom,
RightBottom,
Center
};
bool ApproximatelyEqual(const int a, const int b, int persion)
{
return abs(a-b) < persion ? true : false;
}
protected:
void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
bool event(QEvent *event) Q_DECL_OVERRIDE;
int GetMouseWidgetPos(QPoint p);//获取鼠标所在位置
void setCursorShape(int CalPos);//设置鼠标样式
private:
void InitializationWidget();//窗口初始化
void ShowMaxSize();//窗口最大化
void ShowNormalSize();//窗口非最大化
private slots:
void WinNormalMaxChange();//窗口最大化最小化改变函数
public:
QWidget *centerWidget;//中心widget,可操作空间
MyWidget(QWidget *parent = nullptr);
void SetWinTitle(QString title);//设置窗口标题
void SetWinIcon(QIcon icon);//设置窗口图标
void SetWinIcon(QImage img);
void SetColor(uint r, uint g, uint b);//设置窗口颜色
};
#endif // MYWIDGET_H
MyWidget.cpp
#include "MyWidget.h"
#include
MyWidget::MyWidget(QWidget *parent)
{
setWindowFlags (Qt::FramelessWindowHint);
this->resize(1200, 1000);
m_ismaxed = 0;
m_isleftClicked = 0;
InitializationWidget();
connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
connect(minButton, SIGNAL(clicked()), this, SLOT(showMinimized()));
connect(maxButton, SIGNAL(clicked()), this, SLOT(WinNormalMaxChange()));
setAttribute(Qt::WA_Hover, true);
}
void MyWidget::InitializationWidget()
{
titleWidget = new QWidget();
titleWidget->setStyleSheet("background-color:white;");
titleWidget->resize(1200, 40);
centerWidget = new QWidget();
iconButton = new QToolButton();
iconButton->setFixedSize(40, 40);
iconButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
enum QStyle::StandardPixmap Icon = (enum QStyle::StandardPixmap) 0;
iconButton->setIcon(QApplication::style()->standardIcon(Icon));
iconButton->setStyleSheet("background:transparent");
titleLabel = new QLabel("MyWidget");
titleLabel->setStyleSheet("background:transparent;font-size:18px;border-width:0px");
closeButton = new QPushButton("");
maxButton = new QPushButton("");
minButton = new QPushButton("⎯");
closeButton->setFixedSize(60, 40);
minButton->setFixedSize(60, 40);
maxButton->setFixedSize(60, 40);
minButton->setStyleSheet("QPushButton{border-style:none;background:transparent;font-size:20px;border-width:0px;text-align:center;}"
"QPushButton:hover{background-color:rgb(229, 229, 229);}");
closeButton->setStyleSheet("QPushButton{border-style:none;background:transparent;font-size:20px;border-width:0px;text-align:center;}"
"QPushButton:hover{background-color:rgb(232, 17, 35);color:white;}");
maxButton->setStyleSheet("QPushButton{border-style:none;background:transparent;font-size:20px;border-width:0px;text-align:center;}"
"QPushButton:hover{background-color:rgb(229, 229, 229);}");
//标题widget里边加东西
QSpacerItem *verticalSpacer = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding);
QHBoxLayout *hboxlayout = new QHBoxLayout();
hboxlayout->addWidget(iconButton);
hboxlayout->addWidget(titleLabel);
hboxlayout->addItem(verticalSpacer);
hboxlayout->addWidget(minButton);
hboxlayout->addWidget(maxButton);
hboxlayout->addWidget(closeButton);
hboxlayout->setSpacing(0);
hboxlayout->setContentsMargins(0,0,0,0);
titleWidget->setLayout(hboxlayout);
//设置标题widget与中心widget布局
QVBoxLayout *vboxlayout = new QVBoxLayout();
vboxlayout->addWidget(titleWidget, 1);
vboxlayout->addWidget(centerWidget, 100);
vboxlayout->setSpacing(0);
vboxlayout->setContentsMargins(0,0,0,0);
this->setLayout(vboxlayout);
}
void MyWidget::WinNormalMaxChange()
{
if (m_ismaxed)
{
ShowNormalSize();
}
else
{
ShowMaxSize();
}
}
void MyWidget::ShowMaxSize()
{
winRect = this->geometry();
QRect trect = QApplication::desktop()->screenGeometry();
this->setGeometry(trect);
maxButton->setText("");
m_ismaxed = 1;
}
void MyWidget::ShowNormalSize()
{
this->setGeometry(winRect);
maxButton->setText("");
m_ismaxed = 0;
}
void MyWidget::mousePressEvent(QMouseEvent *event)
{
//左键拖动窗口移动、左键控制移动
if (event->button() == Qt::LeftButton)
{
//为了拖动
m_leftDownp = event->globalPos()-pos();
//为了缩放
m_leftDownMapp = event->globalPos();
m_isleftClicked = 1;
}
QWidget::mousePressEvent(event);
}
void MyWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
// 左键双击最大化
if (event->button() == Qt::LeftButton && titleWidget->geometry().contains(this->mapFromGlobal(QCursor::pos())))
{
if (m_ismaxed)
{
ShowNormalSize();
}
else
{
ShowMaxSize();
}
}
QWidget::mouseDoubleClickEvent(event);
}
void MyWidget::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
m_isleftClicked = 0;
}
}
void MyWidget::mouseMoveEvent(QMouseEvent *event)
{
if (m_isleftClicked)
{
if (titleWidget->geometry().contains(this->mapFromGlobal(QCursor::pos())))
{
//执行移动
this->move(event->globalPos() - m_leftDownp);
}
else
{
//执行缩放
QPoint ptMoveSize = event->globalPos() - m_leftDownMapp;
int CalPos = GetMouseWidgetPos(event->globalPos());
QRect rect = geometry();
switch(CalPos)
{
case LeftUp:
rect.setTopLeft(winRect.topLeft()+ptMoveSize);
break;
case Up:
rect.setTop(winRect.top()+ptMoveSize.y());
break;
case RightUp:
rect.setTopRight(winRect.topRight()+ptMoveSize);
break;
case Left:
rect.setLeft(winRect.left()+ptMoveSize.x());
break;
case Right:
rect.setRight(winRect.right()+ptMoveSize.x());
break;
case LeftBottom:
rect.setBottomLeft(winRect.bottomLeft()+ptMoveSize);
break;
case Bottom:
rect.setBottom(winRect.bottom()+ptMoveSize.y());
break;
case RightBottom:
rect.setBottomRight(winRect.bottomRight()+ptMoveSize);
break;
default:
break;
}
setGeometry(rect);
}
if (!m_ismaxed)
winRect = this->geometry();
}
QWidget::mouseMoveEvent(event);
}
bool MyWidget::event(QEvent *event)
{
//更改鼠标样式
if (event->type() == QEvent::HoverEnter || event->type() == QEvent::HoverLeave || event->type() == QEvent::HoverMove)
{
QHoverEvent* pHoverEvent = static_cast(event);
QPoint cursorPos = mapToGlobal(pHoverEvent->pos());
if(!m_isleftClicked)
{
int CalPos = GetMouseWidgetPos(cursorPos);
setCursorShape(CalPos);
}
}
return QWidget::event(event);
}
int MyWidget::GetMouseWidgetPos(QPoint p)
{
QRect rect = geometry();
int minx = rect.x();
int miny = rect.y();
int maxy = rect.y()+rect.height();
int maxx = rect.x()+rect.width();
int x = p.x();
int y = p.y();
int persion = 5;
if (ApproximatelyEqual(x, minx, persion) && ApproximatelyEqual(y, miny, persion))
return LeftUp;
else if (ApproximatelyEqual(x, minx, persion))
return Left;
else if (ApproximatelyEqual(y, miny, persion))
return Up;
else if (ApproximatelyEqual(x, maxx, persion) && ApproximatelyEqual(y, maxy, persion))
return RightBottom;
else if (ApproximatelyEqual(x, maxx, persion))
return Right;
else if (ApproximatelyEqual(y, maxy, persion))
return Bottom;
else if (ApproximatelyEqual(x, minx, persion) && ApproximatelyEqual(y, maxy, persion))
return LeftBottom;
else if (ApproximatelyEqual(x, maxx, persion) && ApproximatelyEqual(y, miny, persion))
return RightUp;
else
return Center;
}
void MyWidget::setCursorShape(int CalPos)
{
Qt::CursorShape cursor;
switch(CalPos)
{
case LeftUp:
case RightBottom:
cursor = Qt::SizeFDiagCursor;
break;
case RightUp:
case LeftBottom:
cursor = Qt::SizeBDiagCursor;
break;
case Up:
case Bottom:
cursor = Qt::SizeVerCursor;
break;
case Left:
case Right:
cursor = Qt::SizeHorCursor;
break;
default:
cursor = Qt::ArrowCursor;
break;
}
setCursor(cursor);
}
void MyWidget::SetWinTitle(QString title)
{
titleLabel->setText(title);
}
void MyWidget::SetWinIcon(QIcon icon)
{
iconButton->setIcon(icon);
}
void MyWidget::SetWinIcon(QImage img)
{
QPixmap pmap = QPixmap::fromImage(img);
QIcon icon(pmap.scaled(iconButton->width(), iconButton->height()));
iconButton->setIcon(icon);
}
void MyWidget::SetColor(uint r, uint g, uint b)
{
QString str = "background-color:rgb(" + QString::number(r) + "," + QString::number(g) + "," + QString::number(b) + ");";
titleWidget->setStyleSheet(str);
}
调用——main.cpp
#include "MyWidget.h"
#include
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
MyWidget w;
w.SetWinTitle("test");
QImage img("D:/Postgraduate/something/QCoomapTest/QCoomapTest/gui-icon.png");
w.SetWinIcon(img);
w.SetColor(18, 55, 107);
w.show();
return a.exec();
}