很多端游的启动器客户端都是异形窗口,无边框,自绘并重写了最小化、最大化、关闭按钮。本文具体讲一下实现。
步骤:
1,设置窗口透明度、窗口无边框样式、窗口背景透明。
2,准备ps过的带透明通道的不规则png图片,设置为窗口背景。
3,重写鼠标事件实现窗口移动。
看效果:
背景是EA大作《镜之边缘》
上代码:
mainwindow.h
#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_Hmainwindow.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; }main.cpp没有改动,就不贴了。
注意:
1,设置背景图片给centralwidget的stylesheet,而不要设置给mainwindow,否则不显示。
2,qt designer里面拖的控件默认是以UI文件里上层次的控件为父控件,设置父控件的样式会影响子控件的样式,为了不影响,在属性栏设置stylesheet或者代码里设置stylesheet时要加前缀,例如:#myGroupBox{color:red}。注意前缀要和objectName对应。
在代码里设置就是
ui->centralWidget->setStyleSheet("#centralWidget{background-image: url(:/img/bg.png);}");3,以上的移动窗口方法效率不太好,鼠标每次move时都会触发事件,计算位置,移动窗口,重绘窗口,如果不考虑跨平台的话可以用vc的方法。
即:先包含头文件<windows.h>
然后只需要重写mouseMoveEvent一个函数即可。
void MainWindow::mousePressEvent(QMouseEvent *event) { if (ReleaseCapture()) SendMessage(HWND(this->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); event->ignore(); }