• 28877阅读
  • 13回复

Qt--滚动字幕(传说中的跑马灯)【搞定】 [复制链接]

上一主题 下一主题
离线longwenbiao
 
只看楼主 倒序阅读 楼主  发表于: 2010-06-12
— 本帖被 xtfllbl 执行合并操作(2010-06-12) —
小弟最近在做一个LED的模拟程序,碰到了一个问题:
用的是下面这个widget,用来显示滚动字幕,这个程序不错,但是如果动态改变滚动字符的话,滚动字幕会跳动,求高手指教实现平滑改变的方法

请看这里 http://www.qtcn.org/bbs/read.php?tid=25689 9楼贴的方法
[ 此帖被longwenbiao在2010-06-30 15:44重新编辑 ]
离线longwenbiao
只看该作者 1楼 发表于: 2010-06-12
Qt--字幕滚动的程序,也就是传说中的跑马灯
小弟最近在做一个LED模拟程序,碰到一个郁闷的问题:
使用的事这个东东,用来模拟滚动字符label,这个程序估计很多人都看过,问题是如果滚动字符动态改变了,那么会有抖动的效果,不知道怎么是好,请高手指教下。头文件
  1. #ifndef TICKER_H
  2. #define TICKER_H
  3. #include <QWidget>
  4. class Ticker : public QWidget
  5. {
  6.     Q_OBJECT
  7.     Q_PROPERTY(QString text READ text WRITE setText)
  8. public:
  9.     Ticker(QWidget *parent = 0);
  10.     void setText(const QString &newText);
  11.     QString text() const { return myText; }
  12.     QSize sizeHint() const;
  13. protected:
  14.     void paintEvent(QPaintEvent *event);
  15.     void timerEvent(QTimerEvent *event);
  16.     void showEvent(QShowEvent *event);
  17.     void hideEvent(QHideEvent *event);
  18. private:
  19.     QString myText;
  20.     int offset;
  21.     int myTimerId;
  22. };
  23. #endif
  24. cpp文件#include <QtGui>
  25. #include "ticker.h"
  26. Ticker::Ticker(QWidget *parent)
  27.     : QWidget(parent)
  28. {
  29.     offset = 0;
  30.     myTimerId = 0;
  31. }
  32. void Ticker::setText(const QString &newText)
  33. {
  34.     myText = newText;
  35.     update();
  36.     updateGeometry();
  37. }
  38. QSize Ticker::sizeHint() const
  39. {
  40.     return fontMetrics().size(0, text());
  41. }
  42. void Ticker::paintEvent(QPaintEvent * /* event */)
  43. {
  44.     QPainter painter(this);
  45.     int textWidth = fontMetrics().width(text());
  46.     if (textWidth < 1)
  47.         return;
  48.     int x = -offset;
  49.     while (x < width()) {
  50.         painter.drawText(x, 0, textWidth, height(),
  51.                          Qt::AlignLeft | Qt::AlignVCenter, text());
  52.         x += textWidth;
  53.     }
  54. }
  55. void Ticker::showEvent(QShowEvent * /* event */)
  56. {
  57.     myTimerId = startTimer(30);
  58. }
  59. void Ticker::timerEvent(QTimerEvent *event)
  60. {
  61.     if (event->timerId() == myTimerId) {
  62.         ++offset;
  63.         if (offset >= fontMetrics().width(text()))
  64.             offset = 0;
  65.         scroll(-1, 0);
  66.     } else {
  67.         QWidget::timerEvent(event);
  68.     }
  69. }
  70. void Ticker::hideEvent(QHideEvent * /* event */)
  71. {
  72.     killTimer(myTimerId);
  73.     myTimerId = 0;
  74. }
  75. main文件#include <QApplication>
  76. #include "ticker.h"
  77. int main(int argc, char *argv[])
  78. {
  79.     QApplication app(argc, argv);
  80.     Ticker ticker;
  81.     ticker.setWindowTitle(QObject::tr("Ticker"));
  82.     ticker.setText(QObject::tr("How long it lasted was impossible to "
  83.                                "say ++ "));
  84.     ticker.show();
  85.     return app.exec();
  86. }

[ 此帖被xtfllbl在2010-06-13 10:55重新编辑 ]
离线longwenbiao
只看该作者 2楼 发表于: 2010-06-13
顶顶
离线cahwxy

只看该作者 3楼 发表于: 2010-06-13
我自己用Label 自己定制了一个

原理就是:首先计算字符串的长度,在算出每个字符的像素长度,确定显示区
加个定时器,每一个时间间隔显示几个像素,就达到走马灯的效率
离线longwenbiao
只看该作者 4楼 发表于: 2010-06-13
回 3楼(cahwxy) 的帖子
如果显示的字符突然变化了,会不会出现抖动的现象。我这个程序实时性比较高,所以一定要消除抖动现象
离线longwenbiao
只看该作者 5楼 发表于: 2010-06-13
回 3楼(cahwxy) 的帖子
3楼,我的QQ:345931986,能和你讨论下吗?
离线cahwxy

只看该作者 6楼 发表于: 2010-06-13
不会的

说白了就是每隔一段时间调用 setText ,只是每次内容长度不一样而已,所以就是走马灯效果
离线longwenbiao
只看该作者 7楼 发表于: 2010-06-17
回 6楼(cahwxy) 的帖子
cahwxy,能给下你的联系方式吗?
离线jc4123
只看该作者 8楼 发表于: 2010-12-11
学习了,谢谢分享啊
离线cycloneii

只看该作者 9楼 发表于: 2010-12-11
我看电视也好,LED显示牌也好,滚动字幕都是前一条消息显示完了(也就是滚动出了屏幕,此时屏幕没有显示任何字幕),然后才会显示下一条消息。
你要避免滚动,可以,这样作:
1)增加一个成员QString,setText之后暂时不更改mytext变量,只设置这个成员临时保存新的字符串
在79/80行的这个offset回滚成零的时候,将mytext设置临时成员保存的信字符串数值
2)为什么offset是从0到字符串的宽度呢?难道不应该是从-fontMetrics().width(text()) 到+fontMetrics().width(text())?这样的话,字幕才是从最右边一步步的移动到左边,直到完全显示出来,再慢慢的消失?
离线roywillow

只看该作者 10楼 发表于: 2010-12-11
这个例子是Qt4 GUI编程那本上的吧
文本突变的时候确实挺难解决的
不妨用一个QStringList来存储要绘制的文本
然后计算一下一个屏幕现在能绘制多少条文本,然后取出这几条文本在一起绘制出来,绘制完一整条文本后就从QStringList中删掉这一条
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线zzxap

只看该作者 11楼 发表于: 2011-03-23
引用第6楼cahwxy于2010-06-13 11:22发表的  :
不会的
说白了就是每隔一段时间调用 setText ,只是每次内容长度不一样而已,所以就是走马灯效果




这样的效果非常差
离线zxz19871221

只看该作者 12楼 发表于: 2016-10-28
哥们,你这个问题解决了吗?
离线hnxiaofu

只看该作者 13楼 发表于: 2020-03-18
请问怎么解决的
快速回复
限100 字节
 
上一个 下一个