去掉Qt窗口的标题边框,重新定义标题栏,可以在标题栏上实现更多的功能,能满足更多的开发需求,可以实现标题栏的拖动,双击,自定义放大缩小。
本文引用自:http://www.devbean.net/2011/10/custom-qt-titlebar/,感谢原作者,本文对其进行了重新整理,并且修改了一些小问题。
运行界面如下:
详细代码如下:
#include <QWidget>
#include <QToolButton>
#include <QPixmap>
class XMainWindowTitle : public QWidget
{
Q_OBJECT
public:
XMainWindowTitle(QWidget *parent);
public slots:
void showSmall();
void showMaxRestore();
protected:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseDoubleClickEvent(QMouseEvent *e);
private:
QToolButton *minimize;
QToolButton *maximize;
QToolButton *close;
QPixmap restorePix, maxPix;
bool maxNormal;
QPoint startPos;
QPoint clickPos;
};
#include "XMainWindowTitle.h"
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QStyle>
#include <QLabel>
XMainWindowTitle::XMainWindowTitle(QWidget *parent)
{
// 不继承父组件的背景色
setAutoFillBackground(true);
// 使用 Highlight 作为背景色
setBackgroundRole(QPalette::Highlight);
minimize = new QToolButton(this);
maximize = new QToolButton(this);
close= new QToolButton(this);
QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
close->setIcon(pix);
close->setToolTip("close");
close->setStyleSheet("QToolButton:hover{background-color:rgb(219,75,75);}");
maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
maximize->setIcon(maxPix);
maximize->setToolTip("restore");
pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton);
minimize->setIcon(pix);
minimize->setToolTip("minsize");
restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
minimize->setMinimumSize(30,25);
close->setMinimumSize(30,25);
maximize->setMinimumSize(30,25);
QLabel *label = new QLabel(this);
label->setText("Window Title");
parent->setWindowTitle("Window Title");
QHBoxLayout *hbox = new QHBoxLayout(this);
hbox->addWidget(label);
hbox->addWidget(minimize);
hbox->addWidget(maximize);
hbox->addWidget(close);
hbox->insertStretch(1, 500);
hbox->setSpacing(0);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
maxNormal = false;
connect(close, SIGNAL( clicked() ), parent, SLOT(close() ) );
connect(minimize, SIGNAL( clicked() ), this, SLOT(showSmall() ) );
connect(maximize, SIGNAL( clicked() ), this, SLOT(showMaxRestore() ) );
}
void XMainWindowTitle::showSmall()
{
parentWidget()->showMinimized();
}
void XMainWindowTitle::showMaxRestore()
{
if (maxNormal) {
parentWidget()->showNormal();
maxNormal = !maxNormal;
maximize->setIcon(maxPix);
} else {
parentWidget()->showMaximized();
maxNormal = !maxNormal;
maximize->setIcon(restorePix);
}
}
void XMainWindowTitle::mousePressEvent(QMouseEvent *e)
{
startPos = e->globalPos();
clickPos = mapToParent(e->pos());
}
void XMainWindowTitle::mouseMoveEvent(QMouseEvent *e)
{
if (maxNormal)
return;
parentWidget()->move(e->globalPos() - clickPos);
}
void XMainWindowTitle::mouseDoubleClickEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton)
{
showMaxRestore();
}
}
#include "XMainWindowTitle.h"
#include <QFrame>
class XMainWindow : public QFrame
{
public:
XMainWindow();
// 通过 getter 允许外界访问 frame 的 content 区域
// 其它子组件应该添加到这里
QWidget *contentWidget() const ;
XMainWindowTitle *mainWindowTitle() const ;
protected:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
private:
XMainWindowTitle *titleBar;
QWidget *content;
QPoint oldPos;
bool mouseDown;
bool left, right, bottom;
};
#include "XMainWindow.h"
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QDebug>
XMainWindow::XMainWindow()
{
mouseDown = false;
setFrameShape(Panel);
setWindowFlags(Qt::FramelessWindowHint);
setMouseTracking(true);
titleBar = new XMainWindowTitle(this);
titleBar->setCursor(Qt::ArrowCursor);
content = new QWidget(this);
content->setMouseTracking(true);
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->addWidget(titleBar);
vbox->setContentsMargins(0,0,0,0);
vbox->setSpacing(0);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(content);
layout->setContentsMargins(5,5,5,5);
layout->setSpacing(0);
vbox->addLayout(layout);
}
QWidget *XMainWindow::contentWidget() const { return content; }
XMainWindowTitle *XMainWindow::mainWindowTitle() const { return titleBar; }
void XMainWindow::mousePressEvent(QMouseEvent *e)
{
oldPos = e->pos();
mouseDown = e->button() == Qt::LeftButton;
}
void XMainWindow::mouseMoveEvent(QMouseEvent *e)
{
int x = e->x();
int y = e->y();
if (mouseDown) {
int dx = x - oldPos.x();
int dy = y - oldPos.y();
QRect g = geometry();
if (left)
g.setLeft(g.left() + dx);
if (right)
g.setRight(g.right() + dx);
if (bottom)
g.setBottom(g.bottom() + dy);
setGeometry(g);
oldPos = QPoint(!left ? e->x() : oldPos.x(), e->y());
} else {
QRect r = rect();
left = qAbs(x - r.left()) <= 5;
right = qAbs(x - r.right()) <= 5;
bottom = qAbs(y - r.bottom()) <= 5;
bool hor = left | right;
if (hor && bottom) {
if (left)
setCursor(Qt::SizeBDiagCursor);
else
setCursor(Qt::SizeFDiagCursor);
} else if (hor) {
setCursor(Qt::SizeHorCursor);
} else if (bottom) {
setCursor(Qt::SizeVerCursor);
} else {
setCursor(Qt::ArrowCursor);
}
}
}
void XMainWindow::mouseReleaseEvent(QMouseEvent *e)
{
mouseDown = false;
}