Refactor RollingMessageWidget.

This commit is contained in:
Krad
2022-06-07 15:17:46 +08:00
parent c37d1134a6
commit 2892e4e181
2 changed files with 92 additions and 92 deletions

View File

@@ -3,61 +3,67 @@
// //
#include "RollingMessageWidget.h" #include "RollingMessageWidget.h"
#include <QLabel> #include <QLabel>
#include <QThread> #include <QThread>
#include <QDebug> #include <QDebug>
#include <QShowEvent> #include <QShowEvent>
namespace {
const int WAIT_TIMES = 60;
const int LABEL_MARGIN_TOP = 2;
const int LABEL_MARGIN_LEFT = 5;
const int LABEL_FONT_WIDTH = 16;
const int MOVING_STEP = 2;
}
const int WAIT_TIMES = 60; RollingMessageWidget::RollingMessageWidget(QWidget *parent)
: QWidget(parent)
RollingMessageWidget::RollingMessageWidget(QWidget *parent) :QWidget(parent){ , mCurrentLabel(new QLabel(this))
, mNextLabel(new QLabel(this))
{
this->setFixedHeight(36); this->setFixedHeight(36);
// this->setMinimumWidth(1000);
this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred); this->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Preferred);
label_current = new QLabel(this); }
label_next = new QLabel(this);
RollingMessageWidget::~RollingMessageWidget() {
if (mTimerId >= 0) killTimer(mTimerId);
} }
void RollingMessageWidget::timerEvent(QTimerEvent *e) { void RollingMessageWidget::timerEvent(QTimerEvent *e) {
if (!this->isVisible()) return; if (!this->isVisible()) return;
//滚动 //滚动
if (rolling) { if (mRolling) {
//end rolling, reset next //end rolling, reset next
if (rollStep == ROLL_DISTANCE){ if (mRolledDistance == TOTAL_ROLL_DISTANCE){
waitStep = 0; mWaitStep = 0;
rolling = false; mRolling = false;
QPoint p3 = {ROLL_DISTANCE+5,2}; QPoint p3 = {TOTAL_ROLL_DISTANCE + LABEL_MARGIN_LEFT, LABEL_MARGIN_TOP};
// p3.setY(label_next->geometry().y()); mCurrentLabel->move(p3);
label_current->move(p3); std::swap(mCurrentLabel, mNextLabel);
// printf("move last to 505,2\n");
std::swap(label_current,label_next);
return; return;
} }
//rolling //rolling
rollStep+=2; mRolledDistance += 2;
QPoint p1 = {ROLL_DISTANCE+5 - rollStep,2}; QPoint p1 = {TOTAL_ROLL_DISTANCE + LABEL_MARGIN_LEFT - mRolledDistance, LABEL_MARGIN_TOP};
label_next->move(p1); mNextLabel->move(p1);
if (p1.x()-label_current->geometry().x()<=label_current->width()+20) if (p1.x() - mCurrentLabel->geometry().x() <= mCurrentLabel->width() + 20)
{ {
QPoint p2 = {label_current->geometry().x()-2,2}; QPoint p2 = {mCurrentLabel->geometry().x() - MOVING_STEP, LABEL_MARGIN_TOP};
label_current->move(p2); mCurrentLabel->move(p2);
} }
return ; return ;
} }
else{ else{
//有等待的高优先级消息时,不停顿 //有等待的高优先级消息时,不停顿
if (waitStep == WAIT_TIMES || (waitPriorityCount > 0 && waitStep == WAIT_TIMES/3)){ if (mWaitStep == WAIT_TIMES || (mWaitPriorityCount > 0 && mWaitStep == WAIT_TIMES / 3)){
locker.lock(); mLocker.lock();
label_next->setText(getNextMessage()); mNextLabel->setText(getNextMessage());
label_next->setFixedWidth(label_next->text().length()*16); mNextLabel->setFixedWidth(mNextLabel->text().length() * LABEL_FONT_WIDTH);
locker.unlock(); mLocker.unlock();
} else{ } else{
waitStep++; mWaitStep++;
} }
} }
} }
@@ -65,57 +71,54 @@ void RollingMessageWidget::timerEvent(QTimerEvent *e) {
void RollingMessageWidget::setMessageList(const QStringList &message) { void RollingMessageWidget::setMessageList(const QStringList &message) {
//empty, don't set //empty, don't set
if (message.isEmpty()) return; if (message.isEmpty()) return;
messages.clear(); mMessages.clear();
needRolling = false;
// set default label // set default label
label_current->setText(message[0]); mCurrentLabel->setText(message[0]);
messages.push_back({0,message[0],0}); mMessages.push_back({0, message[0], 0});
//add list //add list
if (message.length()>0) if (message.length()>0)
{ {
for (int k = 1; k < message.length(); ++k) { for (int k = 1; k < message.length(); ++k) {
messages.push_front({k, message[k],-1}); mMessages.push_front({k, message[k], -1});
} }
needRolling = true;
} }
} }
void RollingMessageWidget::updateMessagePriority(int innerIndex, int priority) { void RollingMessageWidget::updateMessagePriority(int innerIndex, int priority) {
//lock thread //lock thread
locker.lock(); mLocker.lock();
//高优先级,需要插入 //高优先级,需要插入
if (priority > 0) if (priority > 0)
{ {
int idx = -1, insert_idx = -1; int idx = -1, insertIdx = -1;
for (int i = 0; i < messages.length(); ++i) { for (int i = 0; i < mMessages.length(); ++i) {
if (messages[i].innerId == innerIndex) if (mMessages[i].innerId == innerIndex)
{ {
messages[i].priority = priority; mMessages[i].priority = priority;
idx = i; idx = i;
} }
else if (insert_idx < 0 && messages[i].priority<1) else if (insertIdx < 0 && mMessages[i].priority < 1)
{ {
insert_idx = i; insertIdx = i;
} }
if (idx>=0 && insert_idx >=0) break; if (idx>=0 && insertIdx >= 0) break;
} }
insert_idx = insert_idx==-1?0:insert_idx; insertIdx = insertIdx == -1 ? 0 : insertIdx;
//move //move
if(insert_idx<idx)messages.move(idx,insert_idx); if(insertIdx < idx)mMessages.move(idx, insertIdx);
waitPriorityCount++; mWaitPriorityCount++;
} }
// 低优先级,更新状态即可 // 低优先级,更新状态即可
else{ else{
for (WarnMessage & message : messages) { for (WarnMessage & message : mMessages) {
if (message.innerId == innerIndex) { if (message.innerId == innerIndex) {
message.priority = -1; message.priority = -1;
break; break;
} }
} }
} }
locker.unlock(); mLocker.unlock();
} }
QString RollingMessageWidget::getNextMessage() { QString RollingMessageWidget::getNextMessage() {
@@ -123,44 +126,42 @@ QString RollingMessageWidget::getNextMessage() {
QString ret = "No message"; QString ret = "No message";
int retryCount = 0; int retryCount = 0;
bool priorityFlag = false; bool priorityFlag = false;
while (retryCount<messages.length()){ while (retryCount < mMessages.length()){
messages.move(0,messages.length()-1); mMessages.move(0, mMessages.length() - 1);
retryCount++; retryCount++;
if(messages.last().priority>=0) if(mMessages.last().priority >= 0)
{ {
qDebug()<<"get next:"<<messages.last().toString(); priorityFlag = mMessages.last().priority > 0;
priorityFlag = messages.last().priority>0; ret = mMessages.last().msg;
ret = messages.last().msg; mMessages.last().priority = 0;
messages.last().priority = 0;
break; break;
} }
} }
if (priorityFlag && waitPriorityCount > 0) waitPriorityCount--; if (priorityFlag && mWaitPriorityCount > 0) mWaitPriorityCount--;
rollStep = 0; mRolledDistance = 0;
rolling = true; mRolling = true;
waitStep = 0; mWaitStep = 0;
return ret; return ret;
} }
void RollingMessageWidget::showEvent(QShowEvent *event) { void RollingMessageWidget::showEvent(QShowEvent *event) {
QWidget::showEvent(event); QWidget::showEvent(event);
if (!init) if (!mInitFlag)
{ {
ROLL_DISTANCE = this->width(); TOTAL_ROLL_DISTANCE = this->width();
QPoint p1 = {5,2}; QPoint p1 = {LABEL_MARGIN_LEFT,LABEL_MARGIN_TOP};
label_current->setFixedHeight(30); mCurrentLabel->setFixedHeight(30);
label_current->show(); mCurrentLabel->show();
label_current->move(p1); mCurrentLabel->move(p1);
label_current->setText(tr("Message of warn!")); mCurrentLabel->setText(tr("Message of warn!"));
label_current->setFixedWidth(label_current->text().length()*16); mCurrentLabel->setFixedWidth(mCurrentLabel->text().length() * LABEL_FONT_WIDTH);
QPoint p2 = {ROLL_DISTANCE+5,2}; QPoint p2 = {TOTAL_ROLL_DISTANCE + LABEL_MARGIN_LEFT, LABEL_MARGIN_TOP};
label_next->setFixedHeight(30); mNextLabel->setFixedHeight(30);
label_next->show(); mNextLabel->show();
label_next->move(p2); mNextLabel->move(p2);
label_next->setText(tr("Message2 of warn!")); mNextLabel->setText(tr("Message2 of warn!"));
label_next->setFixedWidth(label_next->text().length()*16); mNextLabel->setFixedWidth(mNextLabel->text().length() * LABEL_FONT_WIDTH);
mTimerId = startTimer(40);
timerId = startTimer(40); mInitFlag = true;
init = true;
} }
} }

View File

@@ -7,9 +7,11 @@
#include <QWidget> #include <QWidget>
#include <QMutex> #include <QMutex>
class QThread; class QThread;
class QLabel; class QLabel;
class QTimerEvent; class QTimerEvent;
class RollingMessageWidget:public QWidget { class RollingMessageWidget:public QWidget {
struct WarnMessage{ struct WarnMessage{
int innerId; int innerId;
@@ -18,13 +20,11 @@ class RollingMessageWidget:public QWidget {
* 优先级默认为0-1不显示1代表插入优先显示 * 优先级默认为0-1不显示1代表插入优先显示
*/ */
int priority; int priority;
QString toString(){
return QString("{innerId:%1, msg:%2, priority:%3}").arg(innerId).arg(msg).arg(priority);
}
}; };
Q_OBJECT Q_OBJECT
public: public:
explicit RollingMessageWidget(QWidget *parent = nullptr); explicit RollingMessageWidget(QWidget *parent = nullptr);
~RollingMessageWidget() override;
void setMessageList(const QStringList& message); void setMessageList(const QStringList& message);
void updateMessagePriority(int innerIndex, int priority); void updateMessagePriority(int innerIndex, int priority);
@@ -33,18 +33,17 @@ protected:
void showEvent(QShowEvent *event) override ; void showEvent(QShowEvent *event) override ;
QString getNextMessage(); QString getNextMessage();
private: private:
int timerId = -1; int mTimerId = -1;
int waitPriorityCount = 0; int mWaitPriorityCount = 0;
int waitStep = 0; int mWaitStep = 0;
int rollStep = 0; int mRolledDistance = 0;
bool needRolling = false; bool mRolling = false;
bool rolling = false; QLabel* mCurrentLabel;
QLabel* label_current = nullptr; QLabel* mNextLabel;
QLabel* label_next = nullptr; QList<WarnMessage> mMessages;
QList<WarnMessage> messages; QMutex mLocker;
QMutex locker; bool mInitFlag = false;
bool init = false; int TOTAL_ROLL_DISTANCE = 2000;
int ROLL_DISTANCE=2000;
}; };