• Qt--无边框窗口完美(FrameLess)实现,包含缩放和移动功能重写。


    前言

    1. Qt原本的窗口虽然可以通过QSS样式进行美化,但是只是对客户区有用,对于客户区是无效的。所以想做出一个比较好看的程序,还得自己重写实现无边框窗口。
    2. Qt实现无边框其实一句代码就可以,但是窗口自带的缩放,移动功和关闭功能都会没有,需要自己重写。
      setWindowFlags(Qt::FramelessWindowHint);

    重写无边框窗口

    1.效果如下

    2.由于无边框窗口没有了标题栏和最小化,最大化,关闭的按钮,所以需要自己布局相对应的控件,并重写事件。我的布局如下

    3.事件对应代码

    展开
    //窗口关闭事件
    void MainWindow::windowClose()
    {
        qApp->exit();
    }
    
    //窗口最小化
    void MainWindow::windowMin()
    {
        this->showMinimized();
    }
    //窗口最大化
    void MainWindow::windowMax()
    {
        isMaxWin=!isMaxWin; 
        if(isMaxWin)    //根据是否最大化窗口,改变对应的图标
        {
            ui->btnMax->setIcon(QIcon(":/icons/normal.png"));
            this->showMaximized();
        }
        else
        {
            ui->btnMax->setIcon(QIcon(":/icons/maxsize.png"));
            this->showNormal();
        }
    }
    
    4.窗口移动事件,需要重写鼠标的点击事件和移动事件
    展开
    void MainWindow::mousePressEvent(QMouseEvent*event)
    {
        if(event->button()==Qt::LeftButton) //如果鼠标左键按下
        {
            isPressed=true;         
            curPos=event->pos();    //记录当前的点击坐标
        }
    }
    
    void MainWindow::mouseMoveEvent(QMouseEvent*event)
    {
        if(isPressed) //如果鼠标左键按下           
        {
            this->move(event->pos()-curPos+this->pos());    //窗口移动
        }
    }
    
    //鼠标释放
    void MainWindow::mouseReleaseEvent(QMouseEvent*event)
    {
        isPressed=false;    
    }
    
    
    3.窗口的缩放功能比较麻烦,需要用到windows的消息机制.代码如下
    展开
    //需要包含头文件
    /*
        #include 
        #include 
    */
    //消息处理
    bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
    {
        int m_nBorder = 5;  //边界宽度
        Q_UNUSED(eventType)
        MSG *param = static_cast(message);
    
        switch (param->message)
        {
        case WM_NCHITTEST:
        {
            int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();
            int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();
    
    
            *result = HTCAPTION;
    
            //判断鼠标位置是否位于窗口边界
            if ((nX > 0) && (nX < m_nBorder))
                *result = HTLEFT;
    
            if ((nX > this->width() - m_nBorder) && (nX < this->width()))
                *result = HTRIGHT;
    
            if ((nY > 0) && (nY < m_nBorder))
                *result = HTTOP;
    
            if ((nY > this->height() - m_nBorder) && (nY < this->height()))
                *result = HTBOTTOM;
    
            if ((nX > 0) && (nX < m_nBorder) && (nY > 0)
                    && (nY < m_nBorder))
                *result = HTTOPLEFT;
    
            if ((nX > this->width() - m_nBorder) && (nX < this->width())
                    && (nY > 0) && (nY < m_nBorder))
                *result = HTTOPRIGHT;
    
            if ((nX > 0) && (nX < m_nBorder)
                    && (nY > this->height() - m_nBorder) && (nY < this->height()))
                *result = HTBOTTOMLEFT;
    
            if ((nX > this->width() - m_nBorder) && (nX < this->width())
                    && (nY > this->height() - m_nBorder) && (nY < this->height()))
                *result = HTBOTTOMRIGHT;
    
            if (*result == HTCAPTION)
            {
                return false;
            }
            return true;
        }
        }
        return QMainWindow::nativeEvent(eventType, message, result);
    }
    

    4.要实现窗口的正常功能,还需要对窗口的Flags进行一些设置,同时也要给父类设置,要不然会有问题的.

    其中 Qt::FramelessWindowHint设置窗口为无边框,Qt::Window表示widegt为窗口,Qt::WindowMinimizeButtonHint 程序在任务栏被点击时能够显示/隐藏.

    一些问题

    1.把以上那些功能实现了,无边框窗口基本可以用了,至于如何用Qss美化,界面如何布局,那就看每个人了,反正可以自己进行定制
    2.由于用到了windows下的消息机制,所以该实现只适用于Windows系统.虽然我在GitHub上找到不少可以跨平台的无边框窗口实现,但是都不是很完美,有兴趣的自己可以去GitHub上去看看.
    3.目前的实现方法都会有一些问题,没有原本的好,但基本不影响使用,如果有需要自己也可以进行优化,所以问题不大.

    完整项目代码

    github: QtFrameLess

    星期五女孩

  • 相关阅读:
    CSS函数: translate、translate3d的使用
    java之流程控制
    typescript 笔记
    STM32 基础学习——GPIO位结构(江科大老师教程)
    win10 火绒 每次打开word、excel都会提示,你要如何打开这个文件
    网络基础知识点
    20.flink流处理和批处理的一些思考(对新手来说很重要)
    【分享】小红书采集图片下载到本地
    APK构建过程-命令行编译
    JavaEE进阶(1)Java EE 简述(Java EE 发展历程、什么是Web开发? Web网站的工作流程、什么是框架?Java EE 框架学习概览)
  • 原文地址:https://www.cnblogs.com/duichoumian/p/16855107.html