關於自定義的Qt無邊框窗體
阿新 • • 發佈:2018-11-30
現在桌面軟體的設計風格已經偏向於扁平化了。那麼基於Qt開發的桌面應用也會常常被提出扁平化無邊框的需求。怎麼去掉應用程式旁邊土到渣的邊框呢?本文應該可以幫到你。
QT += core gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = QBaseFramelessWidget TEMPLATE = app SOURCES += main.cpp\ qbaseframelesswidget.cpp \ settingframelesswidget.cpp HEADERS += qbaseframelesswidget.h \ settingframelesswidget.h
/// qbaseframelesswidget.h #ifndef QBASEFRAMELESSWIDGET_H #define QBASEFRAMELESSWIDGET_H #include <QWidget> #include <QPushButton> #include <QMouseEvent> #include <QStyle> #include <QIcon> #include <QString> #include <QDebug> class QBaseFramelessWidget : public QWidget { Q_OBJECT public: QBaseFramelessWidget(QWidget *parent = 0); ~QBaseFramelessWidget(); virtual void mousePressEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); public: /// 窗體移動事件的點 QPoint windowPos; QPoint mousePos; QPoint dPos; private slots: /// 最小化窗體 void onMin( bool ); /// 關閉窗體 void onClose( bool ); private: /// true表示當前視窗狀態為normal,圖示應顯示為max bool minOrNormal; public: /// 顯示最大或者normal的圖示按鈕 QPushButton* m_minOrNormalPushBtn; /// 關閉按鈕 QPushButton* m_closePushBtn; }; #endif // QBASEFRAMELESSWIDGET_H
/// qbaseframelesswidget.cpp #include "qbaseframelesswidget.h" QBaseFramelessWidget::QBaseFramelessWidget(QWidget *parent) : QWidget(parent) { this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); minOrNormal = true; /// 初始化預設為normal狀態 m_minOrNormalPushBtn = new QPushButton(this); m_closePushBtn = new QPushButton(this); m_minOrNormalPushBtn->raise(); m_closePushBtn->raise(); # if 0 /// 這裡只是做顯示,具體大位置可以自定義設定 m_closePushBtn->setGeometry(QRect(300,8,25,25)); m_minOrNormalPushBtn->setGeometry(QRect(330,8,25,25)); m_closePushBtn->setFlat(true); m_minOrNormalPushBtn->setFlat(true); #endif QIcon icon; if( minOrNormal ){/// true means normal /// normal時顯示最小化圖示 icon = style()->standardIcon( QStyle::SP_TitleBarMinButton ); m_minOrNormalPushBtn->setIcon( icon ); m_minOrNormalPushBtn->setToolTip(QObject::tr("Min")); } icon = style()->standardIcon( QStyle::SP_TitleBarCloseButton ); m_closePushBtn->setIcon( icon ); m_closePushBtn->setToolTip(QObject::tr("Quit")); connect( m_minOrNormalPushBtn, SIGNAL(clicked(bool)), this, SLOT( onMin(bool)) ); connect( m_closePushBtn, SIGNAL(clicked(bool)), this, SLOT( onClose(bool)) ); } QBaseFramelessWidget::~QBaseFramelessWidget() { } void QBaseFramelessWidget::onMin(bool) { if( windowState() != Qt::WindowMinimized ){ setWindowState( Qt::WindowMinimized ); } m_minOrNormalPushBtn->setToolTip(QObject::tr("Min")); } void QBaseFramelessWidget::onClose(bool) { emit close(); } void QBaseFramelessWidget::mousePressEvent(QMouseEvent *event) { this->windowPos = this->pos(); // 獲得部件當前位置 this->mousePos = event->globalPos(); // 獲得滑鼠位置 this->dPos = mousePos - windowPos; // 移動後部件所在的位置 } void QBaseFramelessWidget::mouseMoveEvent(QMouseEvent *event) { this->move(event->globalPos() - this->dPos); }
想要寫出既要無窗體可移動,又要包含自己特性的窗體的話,只需要繼承上面的類,寫一個子類就可以了。
#ifndef SETTINGFRAMELESSWIDGET_H
#define SETTINGFRAMELESSWIDGET_H
#include <QObject>
#include <QWidget>
#include "qbaseframelesswidget.h"
class settingFramelessWidget : public QBaseFramelessWidget
{
public:
settingFramelessWidget();
};
#endif // SETTINGFRAMELESSWIDGET_H
#include "settingframelesswidget.h"
settingFramelessWidget::settingFramelessWidget()
{
}
在main.cpp函式中執行,測試效果:
#include "qbaseframelesswidget.h"
#include <QApplication>
#include "settingframelesswidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// QBaseFramelessWidget w;
// w.show();
settingFramelessWidget sfw;
sfw.show();
return a.exec();
}
生成如下所示的介面: