下面那行按钮实现
//pictruebutton.h #ifndef PICTRUERADIOBUTTON_H #define PICTRUERADIOBUTTON_H #include <QAbstractButton> class PictrueButton : public QAbstractButton { Q_OBJECT public: explicit PictrueButton(QWidget *parent = Q_NULLPTR); ~PictrueButton(); int id()const; void setId(int id); Q_SIGNALS: void entered(); void entered(int); protected: virtual void paintEvent(QPaintEvent *); virtual void enterEvent(QEvent *event); virtual void leaveEvent(QEvent *event); private: bool m_isSelected; int m_id; }; #endif // PICTRUERADIOBUTTON_H //pictruebutton.cpp #include "pictruebutton.h" #include <QPen> #include <QPainter> #include <QDebug> #include <QPainterPath> PictrueButton::PictrueButton(QWidget *parent) :QAbstractButton(parent), m_isSelected(false), m_id(0) { setCheckable(true); setFixedSize(50,10); } PictrueButton::~PictrueButton() { } int PictrueButton::id() const { return m_id; } void PictrueButton::setId(int id) { m_id = id; } void PictrueButton::paintEvent(QPaintEvent *) { QPainter painter(this); QRectF drawRect = this->rect(); QPainterPath drawPath; qDebug()<<drawRect; QPen drawPen; drawPen.setWidth(3); //选中为蓝,未选中为灰 drawPen.setColor(Qt::gray); painter.setPen(drawPen); //抗锯齿 painter.setRenderHint(QPainter::Antialiasing); drawPath.addRoundedRect(drawRect,10,10); painter.setClipPath(drawPath); if(isChecked()) painter.fillRect(drawRect,QColor(0,0,255,128)); else painter.fillRect(drawRect,QColor(128,128,128,128)); } void PictrueButton::enterEvent(QEvent *event) { if(!isChecked()) setChecked(true); emit entered(m_id); return QAbstractButton::enterEvent(event); } void PictrueButton::leaveEvent(QEvent *event) { return QAbstractButton::leaveEvent(event); } //qmainWindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #define RAW_VIEW_SIZE QSize(476,414) #define SCALE_VIEW_PIXMAP (qreal)2/1 //View与图片比例 #define SCALE_BIG_SMALL (qreal)2/1 //图片大小比例 //P1-P8,8个位置,根据需要改动 #define P1 (qreal)0.00 #define P2 (qreal)0.25 #define P3 (qreal)0.50 #define P4 (qreal)0.75 #define P5 (qreal)1.00 #define P6 P4 #define P7 P3 #define P8 P2 #define MID_TYPE 2 #define FPS 60//帧数,每秒 #define DURATION_MS 500//移动一次图元经过时间,毫秒,不得低于帧数 namespace Ui { class MainWindow; } class QGraphicsScene; class QButtonGroup; class MainWindow : public QMainWindow { Q_OBJECT public: enum Rules:int{ RuleA = 1, RuleB = -1, RuleC = 2, RuleD = -2 }; explicit MainWindow(QWidget *parent = 0); ~MainWindow(); int getIndexByRules(int oldIndex,int rule); template<typename T> void rollList(QList<T> &oldList, int dir, int count); void rollItem(int rollDir,unsigned rollCount); public Q_SLOTS: void timerOutFunc(); void nextItem(); void previousItem(); void clickedItemRoll(int type); protected: private: Ui::MainWindow *ui; QTimer *m_timer; QGraphicsScene *m_scene; QLineF midLine; QList<qreal> pointList; QList<QPixmap> pixmapList; QList<qreal> zValueList; QList<qreal> pixmapScaleList; int m_index; Rules currentRule; unsigned m_rollCount; QButtonGroup *btnGroup; bool btnMoveEnable; }; #endif // MAINWINDOW_H下面是滚动的关键代码
void MainWindow::timerOutFunc() { for(int i = 0; i<8; i++) { if(qAbs(midLine.pointAt(pointList[getIndexByRules(i,dir)]).x()-itemList[i]->pos().x())<qAbs(unitList[i])) { if(finishList.contains(i)) continue; itemList[i]->setPos(midLine.pointAt(pointList[getIndexByRules(i,dir)])); //设置新的显示优先级 itemList[i]->setScale(pixmapScaleList[getIndexByRules(i,dir)]); //设置新的类型 itemList[i]->setType(getIndexByRules(i,dir)); //i==7-->最后一个图元移动完成 finishList.append(i); if(finishList.size() == 8) { //循环旋转图元表和图片表 rollList(itemList,dir,1); rollList(pixmapList,dir,1); for(int i = 0; i<8; i++) itemList[i]->setZValue(zValueList[i]); m_timer->stop(); finishList.clear(); if(btnGroup->checkedId()!=itemList[MID_TYPE]->itemId()) btnGroup->button(getIndexByRules(btnGroup->checkedId(),dir))->setChecked(true); if(--m_rollCount) { if(dir == 1) nextItem(); else previousItem(); } break; } } else { //按计算好的移动单位移动一次 itemList[i]->setPos(QPointF(itemList[i]->pos().x()+unitList[i],itemList[i]->pos().y())); //转换因子不是1.0时进行转换设置 if(transScaleList[i] != (qreal)1.0) { itemList[i]->setScale(itemList[i]->scale()*transScaleList[i]); } } m_scene->invalidate(); } } void MainWindow::rollItem(int rollDir, unsigned rollCount) { if(m_timer->isActive()) return; //清除之前的空间差列表和移动单位列表 m_rollCount = rollCount; spaceList.clear(); unitList.clear(); transScaleList.clear(); dir = rollDir; qDebug()<<"rollCount"<<rollCount; for(int i = 0; i<8; i++) { spaceList.append(midLine.pointAt(pointList[getIndexByRules(i,dir)]).x()-itemList[i]->pos().x());//计算移动总距离 unitList.append(spaceList[i]/(FPS*DURATION_MS/1000));//计算移动单个距离 transScaleList.append(pow(pixmapScaleList[getIndexByRules(i,dir)]/pixmapScaleList[i],\ (qreal)1/(FPS*DURATION_MS/1000)));//计算增长倍数 } //启动定时器 m_timer->start(); } void MainWindow::nextItem() { rollItem(1,1); } void MainWindow::previousItem() { rollItem(-1,1); }完整工程代码下载