Qt编写自定义控件:跑马灯文本控件

server/2024/9/23 7:22:48/
#ifndef RUNNINGTEXTWIDGET_H
#define RUNNINGTEXTWIDGET_H#include <QWidget>enum Direction
{North = 0, //上South, //下West,  //左East   //右
};class RunningTextWidget : public QWidget
{Q_OBJECT
public:explicit RunningTextWidget(QWidget *parent = nullptr);void setText(const QString & newText);void setDirection(Direction newDirection);void setSpeed(uint newSpeed);protected:void paintEvent(QPaintEvent *event) override final;private:void onTime();std::shared_ptr<struct RunningTextWidgetPrivate> d_ptr;
};#endif // RUNNINGTEXTWIDGET_H
#include "runningtextwidget.h"
#include <QPainter>
#include <QTimer>struct RunningTextWidgetPrivate
{QString text{"飞流直下三千尺,疑是银河落九天"};QString drawText;QColor textColor{Qt::red};int offset{0};uint changeOffset{6};//调节变化速度RunningTextWidget * p_ptr;QSize verticalTextSize;Direction direction{Direction::South};RunningTextWidget * q_ptr;QTimer timer;void updateText();void updateVerticalTextBoundingSize();void move();
};void RunningTextWidgetPrivate::updateText()
{if(direction == Direction::West || direction == Direction::East){if(direction == Direction::East){drawText.clear();;for (auto it = text.rbegin(); it != text.rend(); ++it){drawText.append(*it);}}else{drawText = text;}}else{if(direction == Direction::South){auto temp = text.split("", Qt::SkipEmptyParts).join("\n");drawText.clear();for (auto it = temp.rbegin(); it != temp.rend(); ++it){drawText.append(*it);}}else{drawText = text.split("", Qt::SkipEmptyParts).join("\n");}updateVerticalTextBoundingSize();}
}void RunningTextWidgetPrivate::updateVerticalTextBoundingSize()
{auto lines = drawText.split("\n");int maxWidth = 0;int totalHeight = 0;auto fontMetrics = q_ptr->fontMetrics();for (const auto &line : lines){int width = fontMetrics.horizontalAdvance(line);if (width > maxWidth){maxWidth = width;}totalHeight += fontMetrics.height();totalHeight += fontMetrics.leading();}totalHeight -= fontMetrics.descent();verticalTextSize = QSize(maxWidth, totalHeight);
}void RunningTextWidgetPrivate::move()
{if(direction == Direction::West){offset -= changeOffset;if(offset < 0 && abs(offset) >= q_ptr->fontMetrics().horizontalAdvance(drawText)){offset = q_ptr->width();}}else if(direction == Direction::East){offset += changeOffset;if(offset > q_ptr->width()){offset = -q_ptr->fontMetrics().horizontalAdvance(drawText);}}else if(direction == Direction::North){offset -= changeOffset;if(offset < 0 && abs(offset) >= verticalTextSize.height()){offset = q_ptr->height();}}else if(direction == Direction::South){offset += changeOffset;if(offset > q_ptr->height()){offset = -verticalTextSize.height();}}
}RunningTextWidget::RunningTextWidget(QWidget *parent): QWidget{parent}
{d_ptr = std::make_shared<RunningTextWidgetPrivate>();d_ptr->q_ptr = this;connect(&d_ptr->timer,&QTimer::timeout,this,&RunningTextWidget::onTime);d_ptr->timer.start(40);auto font = this->font();font.setPixelSize(36);font.setBold(true);setFont(font);d_ptr->updateText();
}void RunningTextWidget::setText(const QString &newText)
{d_ptr->text = newText;d_ptr->offset = 0;d_ptr->updateText();update();
}void RunningTextWidget::setDirection(Direction newDirection)
{d_ptr->direction = newDirection;d_ptr->updateText();
}void RunningTextWidget::setSpeed(uint newSpeed)
{d_ptr->changeOffset = newSpeed;
}void RunningTextWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setFont(this->font());painter.setPen(d_ptr->textColor);auto bRect = painter.boundingRect(rect(),Qt::AlignCenter,d_ptr->drawText);if(d_ptr->direction == Direction::West || d_ptr->direction == Direction::East){painter.drawText(QRect(d_ptr->offset,bRect.y(),bRect.width(),bRect.height()),d_ptr->drawText);}else{painter.drawText(QRect(bRect.x(),d_ptr->offset,bRect.width(),bRect.height()),Qt::AlignCenter,d_ptr->drawText);}
}void RunningTextWidget::onTime()
{d_ptr->move();update();
}
#include "runningtextwidget.h"
#include <QApplication>
#include <QHBoxLayout>
#include <QRandomGenerator>int main(int argc, char *argv[])
{QApplication a(argc, argv);QWidget widget;auto hb = new QHBoxLayout(&widget);for(int i = 0;i < 4;++i){auto w = new RunningTextWidget;w->setDirection(static_cast<Direction>(i));w->setSpeed(QRandomGenerator::global()->bounded(8, 50));hb->addWidget(w);}widget.show();return a.exec();
}


http://www.ppmy.cn/server/90486.html

相关文章

Java 不可变Map练习 (2024.7.28)

CollectionExercise3 package CollectionExercise20240728;import java.util.HashMap; import java.util.Map; import java.util.Set;public class CollectionExercise3 {public static void main(String[] args) {// 不可变的Map集合// Map中键是不可以重复的// Map中的of方法…

外行对自动驾驶汽车的一些想法-2024-

起源 前段时间有关于自动驾驶汽车的讨论&#xff0c;现在热度终于快过去了。 (⊙﹏⊙) 其实&#xff0c;完全不用担心自动驾驶取代人类。 引用 这是一篇24年4月的报道。 上图为引用&#xff0c;可以看到打工人的忙碌。 2023 一个热爱自动驾驶但妥妥外行之人的思考-2023-C…

EXCEL自动公式计算始终为0

如果你的数据单元格的左上角存在绿色的三角小箭头&#xff0c;那么就会造成这种问题&#xff1a; 你的数字是以文本形式存入的单元格 解决办法&#xff1a; 选中数据列&#xff0c;数据->分列 直接选择完成 此时就可以进行公式计算了

自动驾驶论文集

自动驾驶技术的前沿研究涵盖了多个方面&#xff0c;包括感知、决策与规划、传感器融合、仿真与测试、安全性与可靠性等。以下是一些近期关于自动驾驶技术的前沿论文和研究方向&#xff0c;可以通过查找相关的学术数据库和会议论文来进一步了解。 1. **感知与视觉识别**&#x…

学术研讨 | 区块链与隐私计算领域专用硬件研讨会顺利召开

学术研讨 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 近日&#xff0c;国家区块链技术创新中心主办&#xff0c;长安链开源社区支持的“区块链性能优化与融合技术研讨会”顺利召开。当前&#xff0c;区块链与新技术之间的交叉融合和协同创新正成为显…

K210视觉识别模块学习笔记7:多线程多模型编程识别

今日开始学习K210视觉识别模块: 图形化操作函数 亚博智能 K210视觉识别模块...... 固件库: canmv_yahboom_v2.1.1.bin 训练网站: 嘉楠开发者社区 今日学习使用多线程、多模型来识别各种物体 这里先提前说一下本文这次测试实验的结果吧&#xff1a;结果是不太成…

扎克伯格:Llama将成AI界的Linux

&#x1f989; AI新闻 &#x1f680; 扎克伯格&#xff1a;Llama将成AI界的Linux 摘要&#xff1a;Meta创始人兼CEO马克扎克伯格在博文中阐述了Llama开源AI的愿景&#xff0c;认为其有潜力成为AI领域的Linux。他表示&#xff0c;开源AI能满足不同组织的需求&#xff0c;提供数…

C语言之文件操作

一、为什么使用文件&#xff1f; 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运行程序&#xff0c;是看不到上次程序的数据的&#xff0c;如果要将数据进行持久…