去掉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; }