Qt開發:無邊框異形視窗,透明背景,可移動
阿新 • • 發佈:2019-01-01
很多端遊的啟動器客戶端都是異形視窗,無邊框,自繪並重寫了最小化、最大化、關閉按鈕。本文具體講一下實現。
步驟:
1,設定視窗透明度、視窗無邊框樣式、視窗背景透明。
2,準備ps過的帶透明通道的不規則png圖片,設定為視窗背景。
3,重寫滑鼠事件實現視窗移動。
看效果:
背景是EA大作《鏡之邊緣》
上程式碼:
mainwindow.h
mainwindow.cpp#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_btn1_clicked(); void on_btn2_clicked(); private: Ui::MainWindow *ui; bool m_Drag; //記錄滑鼠是否按下 QPoint m_DragPosition;//記錄滑鼠位置 //重寫三個滑鼠事件來實現視窗移動 virtual void mousePressEvent(QMouseEvent *event); virtual void mouseMoveEvent(QMouseEvent *event); virtual void mouseReleaseEvent(QMouseEvent *event); }; #endif // MAINWINDOW_H
main.cpp沒有改動,就不貼了。#include "mainwindow.h" #include "ui_mainwindow.h" #include <QMouseEvent> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //設定屬性(如果為了統一管理樣式,便於子視窗和控制元件繼承,可以把下列語句放到main函式裡),只設置這些的話視窗無法移動 this->setWindowOpacity(1); //視窗整體透明度,0-1 從全透明到不透明 this->setWindowFlags(Qt::FramelessWindowHint); //設定無邊框風格 this->setAttribute(Qt::WA_TranslucentBackground); //設定背景透明,允許滑鼠穿透 } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_btn1_clicked() { //切換背景1 ui->centralWidget->setStyleSheet("#centralWidget{background-image: url(:/img/bg.png);}"); //圖片放到資原始檔裡面 } void MainWindow::on_btn2_clicked() { //切換背景2 ui->centralWidget->setStyleSheet("#centralWidget{background-image: url(:/img/bg2.png);}"); } void MainWindow::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { m_Drag = true; m_DragPosition = event->globalPos() - this->pos(); event->accept(); } } void MainWindow::mouseMoveEvent(QMouseEvent *event) { if (m_Drag && (event->buttons() && Qt::LeftButton)) { move(event->globalPos() - m_DragPosition); event->accept(); } } void MainWindow::mouseReleaseEvent(QMouseEvent *event) { m_Drag=false; }
注意:
1,設定背景圖片給centralwidget的stylesheet,而不要設定給mainwindow,否則不顯示。
2,qt designer裡面拖的控制元件預設是以UI檔案裡上層次的控制元件為父控制元件,設定父控制元件的樣式會影響子控制元件的樣式,為了不影響,在屬性欄設定stylesheet或者程式碼裡設定stylesheet時要加字首,例如:#myGroupBox{color:red}。注意字首要和objectName對應。
在程式碼裡設定就是
ui->centralWidget->setStyleSheet("#centralWidget{background-image:3,以上的移動視窗方法效率不太好,滑鼠每次move時都會觸發事件,計算位置,移動視窗,重繪視窗,如果不考慮跨平臺的話可以用vc的方法。url(:/img/bg.png);}");
即:先包含標頭檔案<windows.h>
然後只需要重寫mouseMoveEvent一個函式即可。
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (ReleaseCapture())
SendMessage(HWND(this->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
event->ignore();
}
最後要說的是,本例並未實現視窗的縮放,無邊框縮放是一個很複雜的問題,後面再說。