• Qt无边框窗口实现拖动和改变大小(Qt::FramelessWindowHint)


    相关资料:

    https://blog.csdn.net/dragoo1/article/details/121163236    原文

    代码实例:

    .pro

     1 QT       += core gui
     2 
     3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
     4 
     5 CONFIG += c++11
     6 
     7 # The following define makes your compiler emit warnings if you use
     8 # any Qt feature that has been marked deprecated (the exact warnings
     9 # depend on your compiler). Please consult the documentation of the
    10 # deprecated API in order to know how to port your code away from it.
    11 DEFINES += QT_DEPRECATED_WARNINGS
    12 
    13 # You can also make your code fail to compile if it uses deprecated APIs.
    14 # In order to do so, uncomment the following line.
    15 # You can also select to disable deprecated APIs only up to a certain version of Qt.
    16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    17 
    18 SOURCES += \
    19     main.cpp \
    20     mainwindow.cpp
    21 
    22 HEADERS += \
    23     mainwindow.h
    24 
    25 FORMS += \
    26     mainwindow.ui
    27 
    28 # Default rules for deployment.
    29 qnx: target.path = /tmp/$${TARGET}/bin
    30 else: unix:!android: target.path = /opt/$${TARGET}/bin
    31 !isEmpty(target.path): INSTALLS += target
    View Code

    main.cpp

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

    mainwindow.h

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <QMainWindow>
     5 
     6 #include <QtGui>
     7 
     8 
     9 #define EDGE_MARGIN 8
    10 
    11 QT_BEGIN_NAMESPACE
    12 namespace Ui { class MainWindow; }
    13 QT_END_NAMESPACE
    14 
    15 class MainWindow : public QMainWindow
    16 {
    17     Q_OBJECT
    18 
    19 public:
    20     explicit MainWindow(QWidget *parent = 0);
    21 protected:
    22     virtual void mouseMoveEvent(QMouseEvent * event);
    23     virtual void mousePressEvent(QMouseEvent * event);
    24     virtual void mouseReleaseEvent(QMouseEvent * event);
    25     virtual void enterEvent(QEvent * event);
    26     virtual void leaveEvent(QEvent * event);
    27 private:
    28     QPoint dragPosition;   //鼠标拖动的位置
    29     enum {nodir,
    30         top = 0x01,
    31         bottom = 0x02,
    32         left = 0x04,
    33         right = 0x08,
    34         topLeft = 0x01 | 0x04,
    35         topRight = 0x01 | 0x08,
    36         bottomLeft = 0x02 | 0x04,
    37         bottomRight = 0x02 | 0x08
    38     } resizeDir; //更改尺寸的方向
    39 
    40 private:
    41     void testEdge(QMouseEvent *event);  //检测鼠标是否接近窗口边缘
    42 
    43 
    44 private:
    45     Ui::MainWindow *ui;
    46 };
    47 #endif // MAINWINDOW_H
    View Code

    mainwindow.cpp

      1 #include "mainwindow.h"
      2 #include "ui_mainwindow.h"
      3 
      4 
      5 #define min(a,b) ((a)<(b)? (a) :(b))
      6 #define max(a,b) ((a)>(b)? (a) :(b))
      7 
      8 
      9 MainWindow::MainWindow(QWidget *parent)
     10     : QMainWindow(parent)
     11     , ui(new Ui::MainWindow)
     12 {
     13     resizeDir = nodir;   //初始化检测方向为无
     14     setWindowFlags(Qt::FramelessWindowHint);  //设置无边框
     15     setMouseTracking(true); //开启鼠标追踪
     16     setMinimumSize(90, 200);
     17 }
     18 
     19 void MainWindow::mousePressEvent(QMouseEvent * event)
     20 {
     21     if (event->button() == Qt::LeftButton)  //每当按下鼠标左键就记录一下位置
     22     {
     23         dragPosition = event->globalPos() - frameGeometry().topLeft();  //获得鼠标按键位置相对窗口左上面的位置
     24     }
     25 }
     26 
     27 void MainWindow::testEdge(QMouseEvent *event)
     28 {
     29     int diffLeft = event->globalPos().x() - frameGeometry().left();      //计算鼠标距离窗口上下左右有多少距离
     30     int diffRight = event->globalPos().x() - frameGeometry().right();
     31     int diffTop = event->globalPos().y() - frameGeometry().top();
     32     int diffBottom = event->globalPos().y() - frameGeometry().bottom();
     33 
     34     Qt::CursorShape cursorShape;
     35 
     36     if(diffTop < EDGE_MARGIN && diffTop>=0){                              //根据 边缘距离 分类改变尺寸的方向
     37         if(diffLeft < EDGE_MARGIN && diffLeft>=0){
     38             resizeDir = topLeft;
     39             cursorShape = Qt::SizeFDiagCursor;
     40         }
     41         else if(diffRight > -EDGE_MARGIN && diffRight<=0){
     42             resizeDir = topRight;
     43             cursorShape = Qt::SizeBDiagCursor;
     44         }
     45         else{
     46             resizeDir = top;
     47             cursorShape = Qt::SizeVerCursor;
     48         }
     49     }
     50     else if(abs(diffBottom) < EDGE_MARGIN && diffBottom<=0){
     51         if(diffLeft < EDGE_MARGIN && diffLeft>=0){
     52             resizeDir = bottomLeft;
     53             cursorShape = Qt::SizeBDiagCursor;
     54         }
     55         else if(diffRight > -EDGE_MARGIN && diffRight<=0){
     56             resizeDir = bottomRight;
     57             cursorShape = Qt::SizeFDiagCursor;
     58         }
     59         else{
     60             resizeDir = bottom;
     61             cursorShape = Qt::SizeVerCursor;
     62         }
     63     }
     64     else if(abs(diffLeft) < EDGE_MARGIN){
     65         resizeDir = left;
     66         cursorShape = Qt::SizeHorCursor;
     67     }
     68     else if(abs(diffRight) < EDGE_MARGIN){
     69         resizeDir = right;
     70         cursorShape = Qt::SizeHorCursor;
     71     }
     72     else{
     73         resizeDir = nodir;
     74         cursorShape = Qt::ArrowCursor;
     75     }
     76 
     77     QApplication::setOverrideCursor(cursorShape);
     78 }
     79 
     80 void MainWindow::mouseMoveEvent(QMouseEvent * event)
     81 {
     82     if (event->buttons() & Qt::LeftButton){                 //如果左键是按下的
     83         if(resizeDir == nodir){                             //如果鼠标不是放在边缘那么说明这是在拖动窗口
     84             move(event->globalPos() - dragPosition);
     85         }
     86         else{
     87             int ptop,pbottom,pleft,pright;                   //窗口上下左右的值
     88             ptop = frameGeometry().top();
     89             pbottom = frameGeometry().bottom();
     90             pleft = frameGeometry().left();
     91             pright = frameGeometry().right();
     92             if(resizeDir & top){                               //检测更改尺寸方向中包含的上下左右分量
     93                 if(height() == minimumHeight()){
     94                     ptop = min(event->globalY(),ptop);
     95                 }
     96                 else if(height() == maximumHeight()){
     97                     ptop = max(event->globalY(),ptop);
     98                 }
     99                 else{
    100                     ptop = event->globalY();
    101                 }
    102             }
    103             else if(resizeDir & bottom){
    104                 if(height() == minimumHeight()){
    105                     pbottom = max(event->globalY(),ptop);
    106                 }
    107                 else if(height() == maximumHeight()){
    108                     pbottom = min(event->globalY(),ptop);
    109                 }
    110                 else{
    111                     pbottom = event->globalY();
    112                 }
    113             }
    114 
    115             if(resizeDir & left){                        //检测左右分量
    116                 if(width() == minimumWidth()){
    117                     pleft = min(event->globalX(),pleft);
    118                 }
    119                 else if(width() == maximumWidth()){
    120                     pleft = max(event->globalX(),pleft);
    121                 }
    122                 else{
    123                     pleft = event->globalX();
    124                 }
    125             }
    126             else if(resizeDir & right){
    127                 if(width() == minimumWidth()){
    128                     pright = max(event->globalX(),pright);
    129                 }
    130                 else if(width() == maximumWidth()){
    131                     pright = min(event->globalX(),pright);
    132                 }
    133                 else{
    134                     pright = event->globalX();
    135                 }
    136             }
    137             setGeometry(QRect(QPoint(pleft,ptop),QPoint(pright,pbottom)));
    138         }
    139     }
    140     else testEdge(event);   //当不拖动窗口、不改变窗口大小尺寸的时候  检测鼠标边缘
    141 }
    142 void MainWindow::mouseReleaseEvent(QMouseEvent *event)
    143 {
    144     if(resizeDir != nodir){         //还原鼠标样式
    145         testEdge(event);
    146     }
    147 }
    148 
    149 void MainWindow::enterEvent(QEvent * event)
    150 {
    151     QWidget::enterEvent(event);
    152 }
    153 
    154 void MainWindow::leaveEvent(QEvent * event)
    155 {
    156     QApplication::setOverrideCursor(Qt::IBeamCursor);
    157     QWidget::leaveEvent(event);
    158 }
    View Code

    mainwindow.ui

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <ui version="4.0">
     3  <class>MainWindow</class>
     4  <widget class="QMainWindow" name="MainWindow">
     5   <property name="geometry">
     6    <rect>
     7     <x>0</x>
     8     <y>0</y>
     9     <width>800</width>
    10     <height>600</height>
    11    </rect>
    12   </property>
    13   <property name="windowTitle">
    14    <string>MainWindow</string>
    15   </property>
    16   <widget class="QWidget" name="centralwidget"/>
    17   <widget class="QMenuBar" name="menubar">
    18    <property name="geometry">
    19     <rect>
    20      <x>0</x>
    21      <y>0</y>
    22      <width>800</width>
    23      <height>22</height>
    24     </rect>
    25    </property>
    26   </widget>
    27   <widget class="QStatusBar" name="statusbar"/>
    28  </widget>
    29  <resources/>
    30  <connections/>
    31 </ui>
    View Code
  • 相关阅读:
    BZOJ-3940:Censoring(AC自动机裸题)
    BZOJ-3881:Divljak (AC自动机+DFS序+树链求并+树状数组)
    CodeForces
    CodeForces 547E:Mike and Friends(AC自动机+DFS序+主席树)
    CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
    CodeForces
    CodeForces
    BZOJ2726:任务安排(DP+斜率优化+二分)
    bzoj 2049: [Sdoi2008]Cave 洞穴勘测
    [SDOI2009]Bill的挑战
  • 原文地址:https://www.cnblogs.com/FKdelphi/p/16450267.html
Copyright © 2020-2023  润新知