Qt Code:
  1. //ticker.h
  2. #ifndef TICKER_H
  3. #define TICKER_H
  4.  
  5. #include <QWidget>
  6.  
  7. class Ticker : public QWidget
  8. {
  9. Q_OBJECT
  10. Q_PROPERTY(QString text READ text WRITE setText)
  11.  
  12. public:
  13. Ticker(QWidget *parent = 0);
  14.  
  15. void setText(const QString &newText);
  16. QString text() const { return myText; }
  17. QSize sizeHint() const;
  18.  
  19. protected:
  20. void paintEvent(QPaintEvent *event);
  21. void timerEvent(QTimerEvent *event);
  22. void showEvent(QShowEvent *event);
  23. void hideEvent(QHideEvent *event);
  24.  
  25. private:
  26. QString myText;
  27. int offset;
  28. int myTimerId;
  29. };
  30.  
  31. #endif
  32.  
  33.  
  34. //ticker.cpp
  35. #include <QtGui>
  36.  
  37. #include "ticker.h"
  38.  
  39. Ticker::Ticker(QWidget *parent)
  40. : QWidget(parent)
  41. {
  42. offset = 0;
  43. myTimerId = 0;
  44. }
  45.  
  46. void Ticker::setText(const QString &newText)
  47. {
  48. myText = newText;
  49. update();
  50. updateGeometry();
  51. }
  52.  
  53. QSize Ticker::sizeHint() const
  54. {
  55. return fontMetrics().size(0, text());
  56. }
  57.  
  58. void Ticker::paintEvent(QPaintEvent * /* event */)
  59. {
  60. QPainter painter(this);
  61.  
  62. int textWidth = fontMetrics().width(text());
  63. if (textWidth < 1)
  64. return;
  65. int x = -offset;
  66. while (x < width()) {
  67. painter.drawText(x, 0, textWidth, height(),
  68. Qt::AlignLeft | Qt::AlignVCenter, text());
  69. x += textWidth;
  70. }
  71. }
  72.  
  73. void Ticker::showEvent(QShowEvent * /* event */)
  74. {
  75. myTimerId = startTimer(30);
  76. }
  77.  
  78. void Ticker::timerEvent(QTimerEvent *event)
  79. {
  80. if (event->timerId() == myTimerId) {
  81. ++offset;
  82. if (offset >= fontMetrics().width(text()))
  83. offset = 0;
  84. scroll(-1, 0);
  85. } else {
  86. QWidget::timerEvent(event);
  87. }
  88. }
  89.  
  90. void Ticker::hideEvent(QHideEvent * /* event */)
  91. {
  92. killTimer(myTimerId);
  93. myTimerId = 0;
  94. }
  95.  
  96. //main.cpp
  97. #include <QApplication>
  98.  
  99. #include "ticker.h"
  100.  
  101. int main(int argc, char *argv[])
  102. {
  103. QApplication app(argc, argv);
  104. Ticker ticker;
  105. ticker.setWindowTitle(QObject::tr("Ticker"));
  106. ticker.setText(QObject::tr("How long it lasted was impossible to "
  107. "say ++ "));
  108. ticker.show();
  109. return app.exec();
  110. }
To copy to clipboard, switch view to plain text mode 

This is an example from C++ GUI programming with Qt4 , second edition.

This example puzzle me.

1 , Q_PROPERTY(QString text READ text WRITE setText). Q_PROPERTY macro is used for declaring properties in classes that inherit QObject. Properties behave like class data members, but they have additional features accessible through the Meta-Object System. But I do think I can do the same thing with QString and the function I write the same with the Q_PROPERTY declare. What's the function of this Q_PROPERTY?

2 , Check all over the code, I can not find any place has called showEvent(), for me, it should not start the timer. But in fact, it does start it and work well. Why?

3 int x = -offset;
while (x < width()) {
painter.drawText(x, 0, textWidth, height(),
Qt::AlignLeft | Qt::AlignVCenter, text());
//.......

The first time of drawText will draw a part of the text outside the widget, and only the fragment inside the widget will show, right?

4 scroll(-1,0); //Scrolls the widget including its children dx pixels to the right and dy downward. Both dx and dy may be negative. After scrolling, the widgets will receive paint events for the areas that need to be repainted. That is to say, the widget can be very long, outside the viewport and only will draw text in the viewport?


Still know little, Thanks for your help!