• Qt 基于Qt的词典开发系列--无边框窗口的缩放与拖动


     在现在,绝大多数软件都向着简洁,时尚发展。就拿有道的单词本和我做的单词本来说,绝大多数用户肯定喜欢我所做的单词本(就单单界面,关于颜色搭配和布局问题,大家就不要在意了)。

    有道的单词本:

    我所做的单词本:

     很明显,两者的主要区别就是周围的边框问题。你可以对比QQ以前的版本和这几年的版本,就会发现都倾向于下面这种窗口模式。下面我们就说说如何用Qt实现无边框窗口的缩放与拖动。
     
            对于无边框窗口的拖动其实很简单,其基本思想是,在鼠标移动前后记录鼠标的坐标,然后将窗口移动这两个坐标之差的距离即可,具体实现可以看代码,就非常清楚了。下面主要讲讲如何实现鼠标改变窗口的大小,首先,我们将一个窗口分为以下9个区域,其中只有鼠标在22区域时无法改变其形状,不能改变窗口大小。当鼠标在其它区域时,鼠标改变形状并可以改变窗口大小。窗口区域分类如下图:

    具体实现如下代码(widget.ui未做任何改变):
    1、widget.h文件
     1 #ifndef WIDGET_H
     2 #define WIDGET_H
     3  
     4 #include <QWidget>
     5 #define MARGIN 20//四个角的长度
     6 namespace Ui {
     7 class Widget;
     8 }
     9  
    10 class Widget : public QWidget
    11 {
    12     Q_OBJECT
    13     
    14 public:
    15     explicit Widget(QWidget *parent = 0);
    16     ~Widget();
    17     int countFlag(QPoint p, int row);
    18     void setCursorType(int flag);
    19     int countRow(QPoint p);
    20  
    21 protected:
    22     void mousePressEvent(QMouseEvent *event);
    23     void mouseReleaseEvent(QMouseEvent *event);
    24     void mouseDoubleClickEvent(QMouseEvent *event);
    25     void mouseMoveEvent(QMouseEvent *event);
    26 private:
    27     Ui::Widget *ui;
    28     bool isLeftPressed;
    29     int curPos;
    30     QPoint pLast;
    31 };
    32  
    33 #endif // WIDGET_H

    2、widget.cpp文件

      1 #include "widget.h"
      2 #include "ui_widget.h"
      3 #include<QMouseEvent>
      4 #include<QDebug>
      5  
      6 Widget::Widget(QWidget *parent) :
      7     QWidget(parent),
      8     ui(new Ui::Widget)
      9 {
     10     ui->setupUi(this);
     11     this->setMouseTracking(true);
     12     //设置在不按鼠标的情况下也触发鼠标移动事件,注意QMainWindow的情况:centralWidget()->setMouseTracking(true);
     13     isLeftPressed=false;
     14     curPos=0;//标记鼠标左击时的位置
     15     this->setMinimumSize(400,300);//设置最小尺寸
     16     QCursor cursor;
     17     cursor.setShape(Qt::ArrowCursor);//设置鼠标为箭头形状
     18    // ui->pushButton->setCursor(cursor);//当放在按钮上时,为箭头
     19    // cursor.setShape(Qt::OpenHandCursor);
     20     QWidget::setCursor(cursor);//当放在主窗口上时,为手形
     21     qDebug()<<"h="<<this->height();
     22     setWindowFlags(Qt::FramelessWindowHint);//设置主窗口无边框
     23     qDebug()<<this->minimumHeight();
     24 }
     25  
     26 Widget::~Widget()
     27 {
     28     delete ui;
     29 }
     30 void Widget::mousePressEvent(QMouseEvent *event)//鼠标按下事件
     31 {
     32     if(event->button()==Qt::LeftButton)
     33     {
     34         this->isLeftPressed=true;
     35         QPoint temp=event->globalPos();
     36         pLast=temp;
     37         curPos=countFlag(event->pos(),countRow(event->pos()));
     38         event->ignore();
     39     }
     40 }
     41  
     42 void Widget::mouseReleaseEvent(QMouseEvent *event)//鼠标释放事件
     43 {
     44     if(isLeftPressed)
     45         isLeftPressed=false;
     46     QApplication::restoreOverrideCursor();//恢复鼠标指针性状
     47     event->ignore();
     48 }
     49  
     50 void Widget::mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击 全屏
     51 {
     52     if(event->button()==Qt::LeftButton)
     53     {
     54         if(windowState()!=Qt::WindowFullScreen)
     55             setWindowState(Qt::WindowFullScreen);
     56         else setWindowState(Qt::WindowNoState);//恢复正常模式
     57     }
     58     event->ignore();
     59 }
     60  
     61 void Widget::mouseMoveEvent(QMouseEvent *event)//鼠标移动事件
     62 {
     63  
     64     int poss=countFlag(event->pos(),countRow(event->pos()));
     65     setCursorType(poss);
     66     if(isLeftPressed)//是否左击
     67     {
     68         QPoint ptemp=event->globalPos();
     69         ptemp=ptemp-pLast;
     70         if(curPos==22)//移动窗口
     71         {
     72             ptemp=ptemp+pos();
     73             move(ptemp);
     74         }
     75         else
     76         {
     77             QRect wid=geometry();
     78  
     79             switch(curPos)//改变窗口的大小
     80             {
     81  
     82             case 11:wid.setTopLeft(wid.topLeft()+ptemp);break;//左上角
     83             case 13:wid.setTopRight(wid.topRight()+ptemp);break;//右上角
     84             case 31:wid.setBottomLeft(wid.bottomLeft()+ptemp);break;//左下角
     85             case 33:wid.setBottomRight(wid.bottomRight()+ptemp);break;//右下角
     86             case 12:wid.setTop(wid.top()+ptemp.y());break;//中上角
     87             case 21:wid.setLeft(wid.left()+ptemp.x());break;//中左角
     88             case 23:wid.setRight(wid.right()+ptemp.x());break;//中右角
     89             case 32:wid.setBottom(wid.bottom()+ptemp.y());break;//中下角
     90             }
     91             setGeometry(wid);
     92         }
     93  
     94  
     95         pLast=event->globalPos();//更新位置
     96     }
     97     event->ignore();
     98 }
     99  
    100  
    101  
    102 int Widget::countFlag(QPoint p,int row)//计算鼠标在哪一列和哪一行
    103 {
    104     if(p.y()<MARGIN)
    105         return 10+row;
    106     else if(p.y()>this->height()-MARGIN)
    107         return 30+row;
    108     else
    109         return 20+row;
    110 }
    111  
    112 void Widget::setCursorType(int flag)//根据鼠标所在位置改变鼠标指针形状
    113 {
    114     Qt::CursorShape cursor;
    115     switch(flag)
    116     {
    117     case 11:
    118     case 33:
    119         cursor=Qt::SizeFDiagCursor;break;
    120     case 13:
    121     case 31:
    122         cursor=Qt::SizeBDiagCursor;break;
    123     case 21:
    124     case 23:
    125         cursor=Qt::SizeHorCursor;break;
    126     case 12:
    127     case 32:
    128         cursor=Qt::SizeVerCursor;break;
    129     case 22:
    130         cursor=Qt::OpenHandCursor;break;
    131     default:
    132        //  QApplication::restoreOverrideCursor();//恢复鼠标指针性状
    133          break;
    134  
    135     }
    136     setCursor(cursor);
    137 }
    138  
    139 int Widget::countRow(QPoint p)//计算在哪一列
    140 {
    141     return (p.x()<MARGIN)?1:(p.x()>(this->width()-MARGIN)?3:2);
    142 }

    3、main.cpp文件

     1 #include<QtWidgets>
     2 #include "widget.h"
     3 int main(int argc, char *argv[])
     4 {
     5     QApplication a(argc, argv);
     6     Widget w;
     7     w.show();
     8     
     9     return a.exec();
    10 }

    程序运行截图如下:

            当你将鼠标放在窗口的边缘时,鼠标会变化形状,表示可以拖动窗口。由于没有关闭窗口,只能在强制关闭窗口。如果想做到和不同窗口实现最小化和关闭窗口的画,我们可以在窗口左上角放置两个ToolButton,并设置autorise属性,加上图片即可。下面给出使用上面的无边框窗口所做的词典软件的主界面:

  • 相关阅读:
    SQL复制多表数据
    ie与firefox 关于js 的差别(转载)
    水晶报表函数大全【收藏】
    ArcGIS Engine对象库
    SQL Server死锁总结(转载)
    C#制作鹰眼全过程(带注释)
    大块鸭
    【经典】jQuery使用大全
    TreeView控件失效引发的思考
    根据数据集动态生成TREE
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13501662.html
Copyright © 2020-2023  润新知