Qt开发:无边框异形窗口,透明背景,可移动

很多端游的启动器客户端都是异形窗口,无边框,自绘并重写了最小化、最大化、关闭按钮。本文具体讲一下实现。


步骤:

1,设置窗口透明度、窗口无边框样式、窗口背景透明。

2,准备ps过的带透明通道的不规则png图片,设置为窗口背景。

3,重写鼠标事件实现窗口移动。


看效果:

背景是EA大作《镜之边缘》

Qt开发:无边框异形窗口,透明背景,可移动_第1张图片


Qt开发:无边框异形窗口,透明背景,可移动_第2张图片


上代码:

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_H
mainwindow.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对应。

Qt开发:无边框异形窗口,透明背景,可移动_第3张图片

在代码里设置就是

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();  
}  


最后要说的是,本例并未实现窗口的缩放,无边框缩放是一个很复杂的问题,后面再说。


你可能感兴趣的:(qt)