Qt下实现在里面添加键值对的两个值,设置其显示模式,使其动态滑动出来
详细功能看代码!
kinfocube.h
/*************************************************=========================================================================== * 模块名称:信息块 KInfoCube * 功能说明:滑动显示信息模块,具有水平显示和垂直显示模式 * --------------------------------------------------------------------------- * 修改日期 姓名 内容 * --------------------------------------------------------------------------- * 2014-10-25 冷光跃 初始版本 * ******************************************************************************/ #ifndef KINFOCUBE_H #define KINFOCUBE_H #include <QWidget> #include <QFrame> #include <QPushButton> #include <QLabel> #include <QParallelAnimationGroup> class KInfoCube : public QFrame { Q_OBJECT public: /* 枚举变量:定义框架显示模式 */ enum FrameDisplayModel { Horizontal, //框架水平显示 Vertical //框架垂直显示 }; /* 枚举变量:定义文字显示模式 */ enum TextDisplayModel { OneLine, //在一行中显示 TwoLine //在两行中显示 }; /* 构造函数,初始化 @param model 显示模式 parent 父窗口 */ explicit KInfoCube(QWidget *parent = 0, FrameDisplayModel frameModel = Horizontal, TextDisplayModel textModel = TwoLine); /* 析构函数,释放没有指明父窗口的元件 */ ~KInfoCube(); /* 添加元素,更新已存在的元素 @param sKey 键 sVlue 值 */ void addItem(const QString& sKey,const QString& sVlue); /* 添加元素,更新已存在的元素 @param pair 存储QPair<QString,QString>类型的键值对 */ void addItem(QPair<QString,QString> pair); /* 添加元素,更新已存在的元素 @param list 存储QList<QPair<QString,QString>>类型的键值对 */ void addItem(QList<QPair<QString,QString>> list); /* 清除所有元素 */ void clear(); /* 设置左边距 @param value 值 */ void setLeftMargin(const int value); /* 设置右边距 @param value 值 */ void setRightMargin(const int value); /* 设置上边距 @param value 值 */ void setTopMargin(const int value); /* 设置下边距 @param value 值 */ void setBottomMargin(const int value); /* 设置元素的宽,框架显示模式为水平时有效 @param value 值 */ void setItemWidth(const int value); /* 设置元素的高,框架显示模式为垂直时有效 @param value 值 */ void setItemHeight(const int value); /* 设置元素之间的间隔 @param value 值 */ void setItemSpacing(const int value); /* 设置按钮的宽 @param value 值 */ void setButtonSize(const int value); /* 设置按钮的样式 @param styleSheet string类型的样式值 */ void setBtnStyleSheet(const QString& styleSheet = "background-color: rgb(255, 0, 127)"); /* 设置框架显示模式 @param frameModel FrameDisplayModel的枚举类型 */ void setFrameDisplayModel(FrameDisplayModel frameModel); /* 设置问子显示模式 @param textModel TextDisplayModel的枚举类型 */ void setTextDisplayModel(TextDisplayModel textModel); /* 开始更新 */ void beginUpdate(); /* 结束更新 */ void endUpdate(); /* 设置文字显示模式 @param aligin 对齐方式 */ void setTextAligin(Qt::Alignment aligin); /* 设置文字的分隔符 @param sSeparator 分隔符 */ void setTextSeparator(const QString& sSeparator); protected: /* 枚举变量:定义元素移动方向 */ enum Direction { Up, // 上 Down, // 下 Left, // 左 Right // 右 }; void initValue(); // 初始化值 void creatFrame(); // 创建框架 void connectSignalSlot(); // 连接信号和曹 void frameLayout(); // 为框架布局 void changeSize(); // 改变框架大小 int findItem(const QString& sKey); // 查找元素,找到返回元素所在的位置,否则返回-1 void creatItemLabel(); // 为每个元素创建label bool isCreateItemLabel(); // 是否已经为元素创建了label,是返回true,不是返回false void showItem(int nPosition); // 显示nPosition开始之后的所有元素 void moveItem(Direction eDirecttion); // 根据eDirecttion的值移动元素的位置 void updateButtonState(); // 更新按钮状态,根据元素的多少显示对应按钮,方便查看 void clearItemLabel(); // 清除所有元素 void layoutControl(); // 重新调整控件 int getFaceWidth(int position); // 获得前面item的总宽度 int getBackPosition(); // 返回能容纳最后几个item的收个位置 void resizeEvent(QResizeEvent* event); // 监听改变窗口大小时的事件 private slots: void clickOnForward(); // 响应向前按钮单击的曹 void clickOnNext(); // 相应向后按钮单击的曹 private: FrameDisplayModel m_eFrameDisModel; // 框架显示模式 TextDisplayModel m_eTextDisModel; // 文字显示模式 QPushButton* btn_forward; // 向前按钮 QPushButton* btn_next; // 向右按钮 QWidget* frameWidget; // 框架的QWidget QList<QPair<QString, QString> > keyValue_list; // 存储元素显示的文字 QList<QLabel*>item_list; // 存储元素 QParallelAnimationGroup* m_pAnimGroup; // 并行动画组 Qt::Alignment m_eItemAligin; // item文本的对齐方式 int m_nButtonSize; // ,在水平显示时是按钮的宽,在垂直显示时是按钮的高 int m_nItemWidth; // 元素label的宽 int m_nItemHeight; // 元素label的高 int m_nTopMargin; // 框架上边距 int m_nBottomMargin; // 框架下边距 int m_nLeftMargin; // 框架左边距 int m_nRightMargin; // 框架右边距 int m_nItemSpacing; // 元素之间的间距 int m_nNowItemPosition; // 当前显示的第一个元素 int m_nUpdateFlags; // 更新标志,0为立即更新,否则等待更新 bool bCreateItemLabel; // 是否为元素文字创建了label QString sItemStyleSheet; // item样式 QString m_sTextSeparator; // 文字之间的分隔符 }; #endif // KINFOCUBE_H
kinfocube.cpp
#include "kinfocube.h" #include <QLayout> #include <QPropertyAnimation> /* 构造函数,初始化 @param model 显示模式 parent 父窗口 */ KInfoCube::KInfoCube(QWidget *parent, FrameDisplayModel frameModel, TextDisplayModel textModel) : QFrame(parent), m_eTextDisModel(textModel), m_eFrameDisModel(frameModel) { initValue(); creatFrame(); connectSignalSlot(); frameLayout(); } /* 析构函数,释放没有指明父窗口的元件 */ KInfoCube::~KInfoCube() { clearItemLabel(); delete m_pAnimGroup; m_pAnimGroup = nullptr; } /* 添加元素,更新已存在的元素 @param sKey 键 sVlue 值 */ void KInfoCube::addItem(const QString &sKey, const QString &sVlue) { int position = findItem(sKey); if(position != -1) { keyValue_list[position].second = sVlue; } else { QPair<QString, QString>newPair; newPair.first = sKey; newPair.second= sVlue; keyValue_list.append(newPair); } layoutControl(); } /* 添加元素,更新已存在的元素 @param pair 存储QPair<QString,QString>类型的键值对 */ void KInfoCube::addItem(QPair<QString, QString> pair) { int position = findItem(pair.first); if(position != -1) { keyValue_list[position].second = pair.second; } else { QPair<QString, QString>newPair; newPair.first = pair.first; newPair.second= pair.second; keyValue_list.append(newPair); } layoutControl(); } /* 添加元素,更新已存在的元素 @param list 存储QList<QPair<QString,QString>>类型的键值对 */ void KInfoCube::addItem(QList<QPair<QString, QString> > list) { for(int i=0; i<list.size(); i++) { int position = findItem(list[i].first); if(position != -1) { keyValue_list[position].second = list.at(i).second; } else { QPair<QString, QString>newPair; newPair.first = list.at(i).first; newPair.second= list.at(i).second; keyValue_list.append(newPair); } } layoutControl(); } /* 清除所有元素 */ void KInfoCube::clear() { keyValue_list.clear(); clearItemLabel(); bCreateItemLabel = false; } /* 设置左边距 @param value 值 */ void KInfoCube::setLeftMargin(const int value) { m_nLeftMargin = value; layoutControl(); } /* 设置右边距 @param value 值 */ void KInfoCube::setRightMargin(const int value) { m_nRightMargin = value; layoutControl(); } /* 设置上边距 @param value 值 */ void KInfoCube::setTopMargin(const int value) { m_nTopMargin = value; layoutControl(); } /* 设置下边距 @param value 值 */ void KInfoCube::setBottomMargin(const int value) { m_nBottomMargin = value; layoutControl(); } /* 设置元素的宽,框架显示模式为水平时有效 @param value 值 */ void KInfoCube::setItemWidth(const int value) { m_nItemWidth = value; layoutControl(); } /* 设置元素的高,框架显示模式为垂直时有效 @param value 值 */ void KInfoCube::setItemHeight(const int value) { m_nItemHeight = value; layoutControl(); } /* 设置元素之间的间隔 @param value 值 */ void KInfoCube::setItemSpacing(const int value) { m_nItemSpacing = value; layoutControl(); } /* 设置按钮的宽 @param value 值 */ void KInfoCube::setButtonSize(const int value) { m_nButtonSize = value; layoutControl(); } /* 设置按钮的样式 @param styleSheet string类型的样式值 */ void KInfoCube::setBtnStyleSheet(const QString &styleSheet) { btn_forward ->setStyleSheet(styleSheet); btn_next ->setStyleSheet(styleSheet); layoutControl(); } /* 设置框架显示模式 @param frameModel FrameDisplayModel的枚举类型 */ void KInfoCube::setFrameDisplayModel(KInfoCube::FrameDisplayModel frameModel) { m_eFrameDisModel = frameModel; layoutControl(); } /* 设置问子显示模式 @param textModel TextDisplayModel的枚举类型 */ void KInfoCube::setTextDisplayModel(KInfoCube::TextDisplayModel textModel) { m_eTextDisModel = textModel; layoutControl(); } /* 开始更新 */ void KInfoCube::beginUpdate() { ++m_nUpdateFlags; } /* 结束更新 */ void KInfoCube::endUpdate() { --m_nUpdateFlags; layoutControl(); } /* 设置文字显示模式 @param aligin 对齐方式 */ void KInfoCube::setTextAligin(Qt::Alignment aligin) { m_eItemAligin = aligin; layoutControl(); } /* 设置文字的分隔符 @param aligin 分隔符 */ void KInfoCube::setTextSeparator(const QString &sSeparator) { m_sTextSeparator = sSeparator; layoutControl(); } /* 初始化值 */ void KInfoCube::initValue() { m_nButtonSize = 20; m_nTopMargin = 6; m_nBottomMargin = 6; m_nLeftMargin = 6; m_nRightMargin = 6; m_nItemSpacing = 6; m_nItemWidth = 60; m_nItemHeight = 60; m_nNowItemPosition = 0; m_nUpdateFlags = 0; bCreateItemLabel = false; m_eItemAligin = Qt::AlignCenter; m_sTextSeparator = ""; } /* 创建框架 */ void KInfoCube::creatFrame() { frameWidget = new QWidget(this); frameWidget->setStyleSheet("background-color: rgb(170, 0, 0)"); btn_forward = new QPushButton(this); btn_next = new QPushButton(this); m_pAnimGroup = new QParallelAnimationGroup();// 并行动画组 } /* 连接信号和曹 */ void KInfoCube::connectSignalSlot() { connect(btn_forward, SIGNAL(clicked()),this,SLOT(clickOnForward())); connect(btn_next, SIGNAL(clicked()),this,SLOT(clickOnNext())); } /* 为框架布局 */ void KInfoCube::frameLayout() { if(m_eFrameDisModel == Horizontal) { btn_forward->move(m_nLeftMargin,m_nTopMargin); btn_next->move(this->geometry().width()-m_nButtonSize-m_nRightMargin,m_nTopMargin); int showBtnSize = 0; showBtnSize += btn_forward->isHidden()?0:m_nButtonSize; frameWidget->move(m_nLeftMargin+showBtnSize,m_nTopMargin); } else { btn_forward ->move(m_nLeftMargin,m_nTopMargin); btn_next->move(m_nLeftMargin,this->geometry().height()-m_nButtonSize-m_nBottomMargin); int showBtnSize = 0; showBtnSize += btn_forward->isHidden()?0:m_nButtonSize; frameWidget->move(m_nLeftMargin,m_nTopMargin+showBtnSize); } } /* 改变框架大小 */ void KInfoCube::changeSize() { if(m_eFrameDisModel == Horizontal) { btn_forward->resize(m_nButtonSize, this->geometry().height()-m_nTopMargin-m_nBottomMargin); btn_next->resize(m_nButtonSize, this->geometry().height()-m_nTopMargin-m_nBottomMargin); int showBtnSize = 0; showBtnSize += btn_forward->isHidden()?0:m_nButtonSize; showBtnSize += btn_next ->isHidden()?0:m_nButtonSize; frameWidget->resize(this->geometry().width()-m_nLeftMargin-m_nRightMargin-showBtnSize, this->geometry().height()-m_nTopMargin-m_nBottomMargin); } else { btn_forward ->resize(this->geometry().width()-m_nLeftMargin-m_nRightMargin, m_nButtonSize); btn_next->resize(this->geometry().width()-m_nLeftMargin-m_nRightMargin, m_nButtonSize); int showBtnSize = 0; showBtnSize += btn_forward->isHidden()?0:m_nButtonSize; showBtnSize += btn_next ->isHidden()?0:m_nButtonSize; frameWidget->resize(this->geometry().width()-m_nLeftMargin-m_nRightMargin, this->geometry().height()-m_nTopMargin-m_nBottomMargin-showBtnSize); } } /* 监听改变窗口大小时的事件 */ void KInfoCube::resizeEvent(QResizeEvent *event) { QFrame::resizeEvent(event); // 根据窗口大小的改变而改变床口内容大小 changeSize(); frameLayout(); if(!isCreateItemLabel()) { creatItemLabel(); bCreateItemLabel = true; } showItem(m_nNowItemPosition); updateButtonState(); } /* 查找元素,找到返回元素所在的位置,否则返回-1 */ int KInfoCube::findItem(const QString &sKey) { for(int i=0; i<keyValue_list.size(); i++) { if(keyValue_list.at(i).first == sKey) return i; } return -1; } /* 为每个元素创建label */ void KInfoCube::creatItemLabel() { clearItemLabel();//在创建之前对其进行清除 // item文字水平显示 if(m_eTextDisModel == OneLine) { for(int i=0; i<keyValue_list.size(); i++) { QString key = keyValue_list.at(i).first; QString value = keyValue_list.at(i).second; QString text = key+m_sTextSeparator+value; QLabel* newItem = new QLabel(frameWidget); newItem->setAlignment(m_eItemAligin); newItem->setTextFormat(Qt::PlainText); newItem->setStyleSheet("background-color: rgb(170, 85, 255)"); newItem->setText(text); item_list.append(newItem); } } // item文字垂直显示 else { for(int i=0; i<keyValue_list.size(); i++) { QString key = keyValue_list.at(i).first; QString value = keyValue_list.at(i).second; QString text = key+"\n"+value; QLabel* newItem = new QLabel(frameWidget); newItem->setAlignment(m_eItemAligin); newItem->setTextFormat(Qt::PlainText); newItem->setStyleSheet("background-color: rgb(170, 85, 255)"); newItem->resize(m_nItemWidth,m_nItemHeight-m_nItemSpacing); newItem->setText(text); item_list.append(newItem); } } } /* 是否已经为元素创建了label,是返回true,不是返回false */ bool KInfoCube::isCreateItemLabel() { return bCreateItemLabel?true:false; } /* 显示nPosition开始之后的所有元素 */ void KInfoCube::showItem(int nPosition) { if (m_eFrameDisModel == Horizontal) { int x = 0; for(int i=0; i<item_list.size(); i++) { item_list.at(i)->adjustSize(); int newWidth = item_list.at(i)->geometry().width(); newWidth = newWidth>m_nItemWidth?newWidth:m_nItemWidth; item_list.at(i)->resize(newWidth ,frameWidget->geometry().height()); if(i<nPosition) { item_list.at(i)->move(-1000,0); } else { item_list.at(i)->move(x,0); x += newWidth+m_nItemSpacing; } item_list.at(i)->show(); } } else { int y = -(m_nNowItemPosition+1)*m_nItemHeight; for(int i=0; i<item_list.size(); i++) { item_list.at(i)->resize(frameWidget->geometry().width(),m_nItemHeight-m_nItemSpacing); item_list.at(i)->move(0,y += m_nItemHeight); item_list.at(i)->show(); } } } /* 根据eDirecttion的值移动元素的位置 */ void KInfoCube::moveItem(KInfoCube::Direction eDirecttion) { m_pAnimGroup->clear(); int x=0; int y=0; int newWidth = m_nItemWidth; switch (eDirecttion) { case Up: y = -(m_nNowItemPosition+1)*m_nItemHeight; for(int i=0; i<item_list.size(); i++) { item_list.at(i)->resize(frameWidget->geometry().width(),m_nItemHeight-m_nItemSpacing); QPropertyAnimation *animation = new QPropertyAnimation(item_list.at(i),"pos"); animation->setDuration(1000); animation->setStartValue(QPoint(0,y)); animation->setEndValue(QPoint(0,y + m_nItemHeight)); animation->setEasingCurve(QEasingCurve::OutBounce); m_pAnimGroup->addAnimation(animation); y += m_nItemHeight; } break; case Down: y = -m_nNowItemPosition*m_nItemHeight; for(int i=0; i<item_list.size(); i++) { item_list.at(i)->resize(frameWidget->geometry().width(),m_nItemHeight-m_nItemSpacing); QPropertyAnimation *animation = new QPropertyAnimation(item_list.at(i),"pos"); animation->setDuration(1000); animation->setStartValue(QPoint(0,y + m_nItemHeight)); animation->setEndValue(QPoint(QPoint(0,y))); animation->setEasingCurve(QEasingCurve::OutBounce); m_pAnimGroup->addAnimation(animation); y += m_nItemHeight; } break; case Left: x = -getFaceWidth(m_nNowItemPosition+1); newWidth = item_list.at(m_nNowItemPosition)->geometry().width(); for(int i=0; i<item_list.size(); i++) { QPropertyAnimation *animation = new QPropertyAnimation(item_list.at(i),"pos"); animation->setDuration(1000); animation->setStartValue(QPoint(x,0)); animation->setEndValue(QPoint(x + newWidth + m_nItemSpacing,0)); animation->setEasingCurve(QEasingCurve::OutBounce); m_pAnimGroup->addAnimation(animation); x += item_list.at(i)->geometry().width()+m_nItemSpacing; } break; case Right: x = -getFaceWidth(m_nNowItemPosition); newWidth = item_list.at(m_nNowItemPosition-1)->geometry().width(); for(int i=0; i<item_list.size(); i++) { QPropertyAnimation *animation = new QPropertyAnimation(item_list.at(i),"pos"); animation->setDuration(1000); animation->setStartValue(QPoint(x + newWidth,0)); animation->setEndValue(QPoint(x,0)); animation->setEasingCurve(QEasingCurve::OutBounce); m_pAnimGroup->addAnimation(animation); x += item_list.at(i)->geometry().width()+m_nItemSpacing; } break; default: break; } m_pAnimGroup->start(); } /* 更新按钮状态,根据元素的多少显示对应按钮,方便查看 */ void KInfoCube::updateButtonState() { bool first = m_nNowItemPosition == 0; // 第一个元素 first?btn_forward->hide():btn_forward->show(); int lastPosition = m_eFrameDisModel == Horizontal? getBackPosition() : item_list.size()-frameWidget->height()/m_nItemHeight; bool last = m_nNowItemPosition >= lastPosition; // 最后一个元素 last?btn_next->hide():btn_next->show(); frameLayout(); changeSize(); showItem(m_nNowItemPosition); } /* 清除所有元素 */ void KInfoCube::clearItemLabel() { for(int i=0; i<item_list.size(); i++) { delete item_list.at(i); } item_list.clear(); } /* 更新,TRUE为立即更新,false为等待更新 */ void KInfoCube::layoutControl() { if(m_nUpdateFlags > 0) return; creatItemLabel(); showItem(m_nNowItemPosition); updateButtonState(); } int KInfoCube::getFaceWidth(int position) { int width = 0; for(int i=0; i<position; i++) { width += item_list.at(i)->geometry().width() + m_nItemSpacing; } return width; } int KInfoCube::getBackPosition() { int width = 0; for(int i=item_list.size()-1; i>=0; i--) { width += item_list.at(i)->geometry().width() + m_nItemSpacing; if(width - m_nItemSpacing>this->geometry().width()) { return i+1; } } } /* 响应向前按钮单击的曹 */ void KInfoCube::clickOnForward() { m_nNowItemPosition--; updateButtonState(); m_eFrameDisModel==Horizontal?moveItem(Left):moveItem(Up); } /* 响应向后按钮单击的曹 */ void KInfoCube::clickOnNext() { m_nNowItemPosition++; updateButtonState(); m_eFrameDisModel==Horizontal?moveItem(Right):moveItem(Down); }
调试效果:
时间: 2024-10-22 00:08:47