• QT实现自定义拖动边框调整窗口大小


    自己开发了一个傅里叶周期分析软件,可用于股票,基金,期货、外汇等数据的周期分析和趋势分析;关注微信公众号:QStockView

    1.QT系统自带的边框就可以实现拖动改变大小的功能,但是有些场景要自定义程序系统的标题栏,要将系统自带的边框标题栏隐藏掉,设置为frameless形式,这时候就要自定义实现窗口边框的拖动改变大小;

     实现思路

    (1)将主窗口按照从上到下分为1、2、3,从左到右分为1、2、3,这样就变成了一个九宫格;鼠标在外层边缘区域时,鼠标自动变为双向箭头的形式,而且在各个区域的鼠标箭头方向也不一样。可以拖动边框改变大小,在其他区域时鼠标是正常的小箭头图标;

    (2)根据鼠标在不同的区域是否按下,并且根据按下的相对位移重新计算窗口的大小,然后resize窗口的大小

    2.实现步骤

    头文件定义变量和函数

    #ifndef FULIYEPERIOD_H
    #define FULIYEPERIOD_H
    
    #include <QtWidgets/QMainWindow>
    #include "ui_dftAnalyze.h"
    #include"NGraph.hpp"
    #include <QAxObject>
    
    #define FRAMESHAPE 10 
    enum {
        TOPLEFT = 11,
        TOP = 12,
        TOPRIGHT = 13,
        LEFT = 21,
        CENTER = 22,
        RIGHT = 23,
        BUTTOMLEFT = 31,
        BUTTOM = 32,
        BUTTOMRIGHT = 33
    };
    
    class FuliyePeriod : public QMainWindow
    {
        Q_OBJECT
    
    public:
        FuliyePeriod(QWidget *parent = 0);
        ~FuliyePeriod();
        void mousePressEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
        void mouseDoubleClickEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
        int CalCursorCol(QPoint pt);    //个位计算鼠标X的在1,2,3哪个区域位置位置 
        int CalCursorPos(QPoint pt, int colPos);    //用十位表示y在1,2,3哪个区域的位置
        void setCursorShape(int CalPos);    //设置鼠标对应位置11,12,13,21,22,23,31,32,33设置鼠标的形状
     private:
        Ui::FlyAnalyze ui;int     m_iCalCursorPos;
        bool    m_bLeftPress;
        QRect   m_rtPreGeometry;
        QPoint  m_ptViewMousePos;
    };
    
    #endif // FULIYEPERIOD_H

    源文件实现函数

    void FuliyePeriod::mousePressEvent(QMouseEvent * event)
    {
        QPoint  pos2 = QCursor::pos();
        pos2 = this->mapFromGlobal(QCursor().pos());//全局坐标转换为主窗口的相对坐标
        m_iCalCursorPos = CalCursorPos(pos2, CalCursorCol(pos2));
        if (event->button() == Qt::LeftButton /*&& Qt::WindowMaximized != windowState()*/)
        {
            if (m_iCalCursorPos != CENTER)
            {
                m_bLeftPress = true;
            }
        }
        m_rtPreGeometry = geometry();
        m_ptViewMousePos = event->globalPos();
    }
    void FuliyePeriod::mouseMoveEvent(QMouseEvent *event)
    {
        //窗体不是最大的话就改变鼠标的形状
        QPoint  pos2 = QCursor::pos();
        pos2 = this->mapFromGlobal(QCursor().pos());
        if (Qt::WindowMaximized != windowState())
        {
            setCursorShape(CalCursorPos(pos2, CalCursorCol(pos2)));
        }
    
        //获取当前的点,这个点是全局的
        QPoint ptCurrentPos = QCursor::pos();
        //计算出移动的位置,当前点 - 鼠标左键按下的点
        QPoint ptMoveSize = ptCurrentPos - m_ptViewMousePos;
        QRect rtTempGeometry = m_rtPreGeometry;
        if (m_bLeftPress)
        {
            switch (m_iCalCursorPos)
            {
            case TOPLEFT:
                rtTempGeometry.setTopLeft(m_rtPreGeometry.topLeft() + ptMoveSize);
                break;
            case TOP:
                rtTempGeometry.setTop(m_rtPreGeometry.top() + ptMoveSize.y());
                break;
            case TOPRIGHT:
                rtTempGeometry.setTopRight(m_rtPreGeometry.topRight() + ptMoveSize);
                break;
            case LEFT:
                rtTempGeometry.setLeft(m_rtPreGeometry.left() + ptMoveSize.x());
                break;
            case RIGHT:
                rtTempGeometry.setRight(m_rtPreGeometry.right() + ptMoveSize.x());
                break;
            case BUTTOMLEFT:
                rtTempGeometry.setBottomLeft(m_rtPreGeometry.bottomLeft() + ptMoveSize);
                break;
            case BUTTOM:
                rtTempGeometry.setBottom(m_rtPreGeometry.bottom() + ptMoveSize.y());
                break;
            case BUTTOMRIGHT:
                rtTempGeometry.setBottomRight(m_rtPreGeometry.bottomRight() + ptMoveSize);
                break;
            default:
                break;
            }
            //移动窗体,如果比最小窗体大,就移动
            if (rtTempGeometry.width() >= 200 && rtTempGeometry.height() >= 300)
                setGeometry(rtTempGeometry);
    
        }
    
    }
    void FuliyePeriod::mouseReleaseEvent(QMouseEvent * event)
    {
        m_bLeftPress = false;
        QApplication::restoreOverrideCursor();
    }

    3.参考文献,修改了一些缺陷;

    https://blog.csdn.net/weixin_40222745/article/details/82142333

    #ifndef FULIYEPERIOD_H#define FULIYEPERIOD_H
    #include <QtWidgets/QMainWindow>#include "ui_dftAnalyze.h"#include"NGraph.hpp"#include <QAxObject>
    #define FRAMESHAPE 10 enum {TOPLEFT = 11,TOP = 12,TOPRIGHT = 13,LEFT = 21,CENTER = 22,RIGHT = 23,BUTTOMLEFT = 31,BUTTOM = 32,BUTTOMRIGHT = 33};
    class FuliyePeriod : public QMainWindow{Q_OBJECT
    public:FuliyePeriod(QWidget *parent = 0);~FuliyePeriod();//int dftAnalyzeStock(QString strCode);//void mousePressEvent(QMouseEvent *event);//void mouseReleaseEvent(QMouseEvent *event);//void mouseDoubleClickEvent(QMouseEvent *event);void mousePressEvent(QMouseEvent *event);void mouseReleaseEvent(QMouseEvent *event);void mouseDoubleClickEvent(QMouseEvent *event);void mouseMoveEvent(QMouseEvent *event);int CalCursorCol(QPoint pt);    //个位计算鼠标X的在1,2,3哪个区域位置位置 int CalCursorPos(QPoint pt, int colPos);    //用十位表示y在1,2,3哪个区域的位置void setCursorShape(int CalPos);    //设置鼠标对应位置11,12,13,21,22,23,31,32,33设置鼠标的形状//void showEvent(QShowEvent *e);public slots:void dftAnalyzeStock();void InputExcelData();void SlotWaringDialog(int errorcode, QString strContent);private:Ui::FlyAnalyze ui;NGraph m_original;NGraph* m_graph = NULL;int m_topN = 5;QString m_strCode;QFrame m_lineVertival;QString m_defalutPath = "";bool m_leftMousePressed=false;QPoint m_StartPoint;int     m_iCalCursorPos;bool    m_bLeftPress;QRect   m_rtPreGeometry;QPoint  m_ptViewMousePos;};
    #endif // FULIYEPERIOD_H
     
  • 相关阅读:
    10. 正则表达式匹配
    5. 最长回文子串
    板子总结
    2020: 学生查询
    解决apt-get出错
    03如何计算算法的复杂度
    ad如何从PCB中导出元件封装库
    调车遇到的问题及解决办法
    java报错与解决方法总结
    SWD下载k60
  • 原文地址:https://www.cnblogs.com/bclshuai/p/16214529.html
Copyright © 2020-2023  润新知