Qt無邊框視窗,自由縮放視窗大小
阿新 • • 發佈:2019-01-04
1,簡介
之前介紹過實現無邊框視窗的簡單方法,包含了標題的拖拽、最大最小關閉按鈕,雙擊最大化恢復等功能。
如圖:
但是這個方案有一個缺陷,那就是不能自由縮放視窗尺寸。
如果預設尺寸不是很適合內容,那麼只能選擇最大化。
在網上找了一些方案,不是太理想。
要麼是有細節處理不完美,要麼是實現方式太過複雜,有一群類需要自己認真剝離出來。
而我直觀感覺,應該是很簡單就可以解決的,不就是拖拽時改變視窗大小嘛,於是試了試果然很簡單。
效果個人感覺還OK,其中縮放圖示依舊是自己PS畫的
網上找了些帶縮放的視窗,瞭解了大致樣式,然後按照自己需要的圖示大小畫,這樣比較清晰
另外,關於無邊框視窗縮放,博主“ 一去丶二三裡”做了比較完美的實現,推薦大家使用此方法:
此文也是我再看到該部落格之前自己研究所做,留下僅供學習參考。
2,效果
3,原理
原理很簡單
就是底部做了一個水平佈局的widget,最右側放一個圖片label,該label設定滑鼠樣式為縮放型。
給label過濾滑鼠訊息,按下、移動、彈起
在按下時記錄按下位置;在移動時,計算相對按下時的滑鼠偏移;在鬆開時設定視窗尺寸。
4,主要程式碼
MainWindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QMouseEvent> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); protected: bool eventFilter(QObject *obj, QEvent *event); void mousePressEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); private slots: void on_btnMin_clicked(); void on_btnMax_clicked(); void on_btnExit_clicked(); private: Ui::MainWindow *ui; //標題拖動、雙擊最大化 bool mDrag; QPoint mDragPos; bool mIsMax; QRect mLocation; QFont mIconFont; //與縮放相關的變數 int mZoom; QRect mZoomLocation; QPoint mZoomPos; }; #endif // MAINWINDOW_H
MainWindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDesktopWidget> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setWindowFlags(Qt::FramelessWindowHint); mLocation = this->geometry(); mIsMax = false; mDrag = false; mZoom = false; ui->widgetTitle->installEventFilter(this); ui->btnMin->setIcon(QIcon(":/image/min.png")); ui->btnMax->setIcon(QIcon(":/image/max1.png")); ui->btnExit->setIcon(QIcon(":/image/exit.png")); //給縮放的圖片label處理滑鼠的按下、移動、彈起訊息,進行縮放視窗功能 ui->labelZoom->installEventFilter(this); ui->labelZoom->setCursor(Qt::SizeFDiagCursor); setStyleSheet("QMainWindow{color:#E8E8E8;background:#43CD80;}"); //另外在設計器內檢視widgetTitle樣式,內有標題欄各個子控制元件的樣式設定 } MainWindow::~MainWindow() { delete ui; } bool MainWindow::eventFilter(QObject *obj, QEvent *e) { if (obj == ui->widgetTitle) { if(e->type() == QEvent::MouseButtonDblClick) { on_btnMax_clicked(); return true; } } else if (obj == ui->labelZoom) { //實現拖動右下角縮放視窗 if(e->type() == QEvent::MouseButtonPress) { QMouseEvent *event = (QMouseEvent *)e; if (event->buttons() & Qt::LeftButton) { if(mIsMax) { //已最大化,就不讓再拖動 return true; } mZoom = true; mZoomLocation = geometry(); mZoomPos = event->globalPos(); return true; } } else if(e->type() == QEvent::MouseMove) { QMouseEvent *event = (QMouseEvent *)e; if (mZoom && (event->buttons() & Qt::LeftButton)) { int dx = event->globalPos().x() - mZoomPos.x(); int dy = event->globalPos().y() - mZoomPos.y(); QRect rc = mZoomLocation; rc.setRight(rc.right() + dx); rc.setBottom(rc.bottom() + dy); setGeometry(rc); update(); return true; } } else if(e->type() == QEvent::MouseButtonRelease) { mZoom = false; return true; } } return QObject::eventFilter(obj, e); } void MainWindow::mousePressEvent(QMouseEvent *e)//滑鼠按下事件 { if (e->button() == Qt::LeftButton) { mDrag = true; mDragPos = e->globalPos() - pos(); e->accept(); } } void MainWindow::mouseMoveEvent(QMouseEvent *e)//滑鼠移動事件 { if (mDrag && (e->buttons() && Qt::LeftButton)) { move(e->globalPos() - mDragPos); e->accept(); } } void MainWindow::mouseReleaseEvent(QMouseEvent *e)//滑鼠釋放事件 { mDrag = false; } void MainWindow::on_btnMin_clicked() { showMinimized(); } void MainWindow::on_btnMax_clicked() { if (mIsMax) { setGeometry(mLocation); ui->btnMax->setIcon(QIcon(":/image/max1.png")); ui->btnMax->setToolTip(QStringLiteral("最大化")); } else { mLocation = geometry(); setGeometry(qApp->desktop()->availableGeometry()); ui->btnMax->setIcon(QIcon(":/image/max2.png")); ui->btnMax->setToolTip(QStringLiteral("還原")); } mIsMax = !mIsMax; } void MainWindow::on_btnExit_clicked() { qApp->exit(); }