Qt实现可拖动按钮

时间:2022-08-26 19:23:36

本文实例为大家分享了Qt实现可拖动按钮的具体代码,供大家参考,具体内容如下

Qt实现可拖动按钮

直接上代码

self-contained.h

?
1
2
3
4
5
6
7
8
9
10
11
#ifndef SELFCONTAINED_H
#define SELFCONTAINED_H
 
#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QImage>
#include <QMouseEvent>
#include <QVector>
 
#endif // SELFCONTAINED_H

按钮控件

drawbutton.h:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#ifndef DRAGBUTTON_H
#define DRAGBUTTON_H
 
#include "self-contained.h"
 
class DragButton : public QWidget
{
  Q_OBJECT
public:
  DragButton(QWidget *parent = 0);
 
  void setInitialScaling(double scaling);
  void setPixmap(QString pixmap);
  void setText(QString str);
  void setIsHold(bool flag);
protected:
  int isPress;
  int isHold;
 
  QTimer *m_aniTimer;
  QTimer *m_holdTimer;
 
  double m_scaling;
  double m_InitialScaling;//当前缩放比例
  QPoint m_mouseSrcPos;//最小缩放比例
 
  QPixmap m_pixmap;
  QString m_text;
 
  void paintEvent(QPaintEvent *);
  void enterEvent(QEvent *);
  void leaveEvent(QEvent *);
  void mousePressEvent(QMouseEvent *);
  void mouseReleaseEvent(QMouseEvent *);
  void mouseMoveEvent(QMouseEvent *);
 
signals:
  void release_signal();
  void drag_signal();//拖动时发出信号
  void clicked();
public slots:
  void zoomIn();//放大
  void zoomOut();//缩小
  void hold_slot();
};
 
#endif // DRAGBUTTON_H

drawbutton.cpp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "dragbutton.h"
 
DragButton::DragButton(QWidget *parent) :
  QWidget(parent),isPress(0),isHold(0),m_scaling(0.5),m_InitialScaling(0.5),m_mouseSrcPos(0,0)
{
  m_aniTimer = new QTimer(this);
  m_aniTimer->setInterval(7);
 
  m_holdTimer = new QTimer(this);
  m_holdTimer->setInterval(1000);
  m_holdTimer->setSingleShot(true);
  connect(m_holdTimer,SIGNAL(timeout()),this,SLOT(hold_slot()));
}
 
void DragButton::setInitialScaling(double scaling)
{
  if(scaling <= 1 && scaling > 0)
  {
    m_InitialScaling = scaling;
    m_scaling = scaling;
  }
}
 
void DragButton::setPixmap(QString pixmap)
{
  m_pixmap.load(pixmap);
  update();
}
 
void DragButton::setText(QString str)
{
  m_text = str;
  update();
}
 
void DragButton::setIsHold(bool flag)
{
  isHold = flag;
  update();
}
 
void DragButton::paintEvent(QPaintEvent *)
{
  if(m_pixmap.isNull())
    return;
 
  QPainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing);
 
  if(isPress)
  {
    painter.setPen(Qt::NoPen);
    painter.setBrush(QColor(0,0,0,130));
    painter.drawRoundedRect(rect(),20,20);
  }
 
  m_pixmap = m_pixmap.scaled(width(),height() - 20,Qt::KeepAspectRatio,Qt::SmoothTransformation);
 
  int w = m_pixmap.width()*m_scaling;
  int h = m_pixmap.height()*m_scaling;
  painter.drawPixmap(QRect((width() - w)/2,(height() - h)/2 - 20,w,h),
            m_pixmap,m_pixmap.rect());
 
  painter.setPen(QColor(0,0,0));
  painter.drawText(QRect(0,height() - 40,width(),40),Qt::AlignCenter,m_text);
}
 
void DragButton::enterEvent(QEvent *)
{
  disconnect(m_aniTimer,SIGNAL(timeout()),this,SLOT(zoomOut()));
  connect(m_aniTimer,SIGNAL(timeout()),this,SLOT(zoomIn()));
 
  m_aniTimer->start();
}
 
void DragButton::leaveEvent(QEvent *)
{
  disconnect(m_aniTimer,SIGNAL(timeout()),this,SLOT(zoomIn()));
  connect(m_aniTimer,SIGNAL(timeout()),this,SLOT(zoomOut()));
 
  m_aniTimer->start();
}
 
void DragButton::mousePressEvent(QMouseEvent *e)
{
  if(!isHold)
    isPress = 1;
 
  m_holdTimer->start();
 
  m_mouseSrcPos = e->pos();
 
  update();
}
 
void DragButton::mouseReleaseEvent(QMouseEvent *e)
{
  m_holdTimer->stop();
 
  isPress = 0;
  isHold = 0;
 
  if(rect().contains(e->pos()))
    emit clicked();
 
  emit release_signal();
 
  update();
}
 
void DragButton::mouseMoveEvent(QMouseEvent *e)
{
  if(isHold)
  {
    move(pos() - m_mouseSrcPos + e->pos());
    emit drag_signal();
  }
  else
    m_mouseSrcPos = e->pos();
}
 
void DragButton::zoomIn()
{
  m_scaling += 0.01;
  if(m_scaling >= 1)
  {
    m_scaling = 1;
    m_aniTimer->stop();
  }
  update();
}
 
void DragButton::zoomOut()
{
  m_scaling -= 0.01;
  if(m_scaling <= m_InitialScaling)
  {
    m_scaling = m_InitialScaling;
    m_aniTimer->stop();
  }
  update();
}
 
void DragButton::hold_slot()
{
  isHold = 1;
  isPress = 0;
  m_aniTimer->stop();
  m_scaling = m_InitialScaling;
 
  update();
}

整合按钮的控件

drawwidget.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "dragbutton.h"
 
class DragWidget : public QWidget
{
  Q_OBJECT
 
public:
  DragWidget(QWidget *parent = 0);
  ~DragWidget();
 
  void addButton(DragButton*);
 
protected:
  QVector<DragButton*> BtnVector;
  QPoint m_mouseSrcPos;//记录坐标点
 
  void resetInterface();//复位
 
signals:
 
public slots:
  void BtnMove_slots();
  void BtnRelease_slots();
};
 
#endif // DRAGWIDGET_H

drawwidget.cpp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "dragwidget.h"
 
DragWidget::DragWidget(QWidget *parent)
  : QWidget(parent),m_mouseSrcPos(0,0)
{
}
 
DragWidget::~DragWidget()
{
 
}
 
void DragWidget::addButton(DragButton* btn)
{
  connect(btn,SIGNAL(drag_signal()),this,SLOT(BtnMove_slots()));
  connect(btn,SIGNAL(release_signal()),this,SLOT(BtnRelease_slots()));
 
 
  BtnVector.push_back(btn);
  btn->show();
  resetInterface();
}
 
void DragWidget::resetInterface()
{
  for(int i = 0;i < BtnVector.length();++i)
  {
    BtnVector[i]->setGeometry(i * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
  }
}
 
void DragWidget::BtnMove_slots()
{
  for(int i = 0;i < BtnVector.length();++i)//找到鼠标所在的按钮
    if(BtnVector[i] == sender())
    {
      int flag = (BtnVector[i]->pos().x() + BtnVector[i]->width()/2)/(width()/BtnVector.length());
 
      for(int l = 0;l < BtnVector.length();++l)//这里也可以做动画,但这次主要实现拖动的功能
      {
        if(l < i && l <flag)
          BtnVector[l]->setGeometry(l * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
        else if((l > i && l <= flag)||(l >= flag && l < i))
          BtnVector[l]->setGeometry((l + ((i-flag)>0?1:-1))* width()/BtnVector.length(),0,width()/BtnVector.length(),height());
        else if(l > flag && l > i)
          BtnVector[l]->setGeometry(l * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
      }
      //注释部分合为上面的循环
//      if(flag >= i)//往后拖
//        for(int l = 0;l < BtnVector.length();++l)
//        {
//          if(l < i)
//            BtnVector[l]->setGeometry(l * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
//          else if(l > i && l <= flag)
//            BtnVector[l]->setGeometry((l - 1)* width()/BtnVector.length(),0,width()/BtnVector.length(),height());
//          else if(l > flag)
//            BtnVector[l]->setGeometry(l * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
//        }
//      else if(flag < i)//往前拖
//        for(int l = 0;l < BtnVector.length();++l)
//        {
//          if(l < flag)
//            BtnVector[l]->setGeometry(l * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
//          else if(l >= flag && l < i)
//            BtnVector[l]->setGeometry((l + 1)* width()/BtnVector.length(),0,width()/BtnVector.length(),height());
//          else if(l > i)
//            BtnVector[l]->setGeometry(l * width()/BtnVector.length(),0,width()/BtnVector.length(),height());
//        }
      break;
    }
}
 
void DragWidget::BtnRelease_slots()
{
  for(int i = 0;i < BtnVector.length();++i)//找到鼠标所在的按钮
    if(BtnVector[i] == sender())
    {
      int posX = BtnVector[i]->pos().x();
      if(posX < 0)
        posX = 0;
      else if(posX > width())
        posX = width();
 
      int flag = (posX+BtnVector[i]->width()/2)/(width()/BtnVector.length());
 
      DragButton *btn = BtnVector[i];//修改vector顺序
      if(flag >= i)
        for(int l = i;l < flag;++l)
          BtnVector[l] = BtnVector[l+1];
      else
        for(int l = i;l > flag;--l)
          BtnVector[l] = BtnVector[l-1];
 
      BtnVector[flag] = btn;
    }
 
  resetInterface();//复位
}

使用

main.cpp

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "dragwidget.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
 
  DragWidget ww;
  ww.setGeometry(200,200,800,200);
 
  DragButton w(&ww);
  w.setPixmap(":/image/image/contacts.png");
  w.setText("按钮1");
  w.setInitialScaling(0.6);
 
  DragButton w2(&ww);
  w2.setPixmap(":/image/image/time.png");
  w2.setText("按钮2");
  w2.setInitialScaling(0.6);
 
  DragButton w3(&ww);
  w3.setPixmap(":/image/image/checking.png");
  w3.setText("按钮3");
  w3.setInitialScaling(0.6);
 
  DragButton w4(&ww);
  w4.setPixmap(":/image/image/suitcase.png");
  w4.setText("按钮4");
  w4.setInitialScaling(0.6);
 
  ww.addButton(&w);
  ww.addButton(&w2);
  ww.addButton(&w3);
  ww.addButton(&w4);
  ww.show();
 
  return a.exec();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/BIG_C_GOD/article/details/53384785