Qt---實現一組可拖動按鈕
阿新 • • 發佈:2019-01-22
直接上程式碼
self-contained.h
#ifndef SELFCONTAINED_H
#define SELFCONTAINED_H
#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QImage>
#include <QMouseEvent>
#include <QVector>
#endif // SELFCONTAINED_H
按鈕控制元件
drawbutton.h:
#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
#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
#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
#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
#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();
}