QBasicTimer

介绍:

1.QBasicTimer是一个用于计时器的低级类。与QTimer不同,QBasicTimer不继承QObject;当经过一定时间后,它不会发出timeout()信号,而是向我们选择的QTimerEvent发送一个QTimerEvent。这使得QBasicTimer成为QTimer更轻量级的替代品。Qt的内置小部件在内部使用它,并且在Qt的API中为高度优化的应用程序(比如嵌入式应用程序)提供了它。

2.如果希望在应用程序中使用计时器,我们建议使用更高级别的QTimer类而不是这个类。注意,这个计时器是一个重复计时器,除非调用stop()函数,否则它将发送后续计时器事件。

3.要使用这个类,请创建QBasicTimer,并使用超时间隔和指向QObject子类的指针调用它的start()函数。当计时器超时时,它将向QObject子类发送一个计时器事件。使用stop()可以在任何时候停止计时器。isActive()为正在运行的计时器返回true;也就是说,它已经启动,还没有达到超时时间,还没有停止。可以使用timerId()检索计时器的ID。

下面我们用一个小例子来演示QBasicTimer的使用方法

 

QBasicTimer_第1张图片

 

例子详解:

该示例由两个类组成:

Dialog是允许用户输入文本的Dialog小部件。它结合了一个WigglyWidget和一个QLineEdit。

我们首先快速浏览一下Dialog类,然后再看一下WigglyWidget类。要使用这个类,请创建QBasicTimer,并使用超时间隔和指向QObject子类的指针调用它的start()函数。当计时器超时时,它将向QObject子类发送一个计时器事件。使用stop()可以在任何时候停止计时器。isActive()为正在运行的计时器返回true;也就是说,它已经启动,还没有达到超时时间,还没有停止。可以使用timerId()检索计时器的ID。

 

Dialog Class Definition

 class Dialog : public QDialog
  {
      Q_OBJECT

  public:
      explicit Dialog(QWidget *parent = 0);
  };

 Dialog类提供了一个允许用户输入文本的对话框小部件。然后文本由WigglyWidget呈现。

Dialog Class Implementation

 Dialog::Dialog(QWidget *parent)
      : QDialog(parent)
  {
      WigglyWidget *wigglyWidget = new WigglyWidget;
      QLineEdit *lineEdit = new QLineEdit;

      QVBoxLayout *layout = new QVBoxLayout(this);
      layout->addWidget(wigglyWidget);
      layout->addWidget(lineEdit);

      connect(lineEdit, &QLineEdit::textChanged, wigglyWidget, &WigglyWidget::setText);
      lineEdit->setText(tr("Hello world!"));

      setWindowTitle(tr("Wiggly"));
      resize(360, 145);
  }

在构造函数中,我们创建一个带有行编辑的wiggly小部件,并将两个小部件置于垂直布局中。我们将行编辑的textChanged()信号连接到wiggly小部件的setText()槽,以获得与wiggly小部件的实时交互。小部件的默认文本是“Hello world!”

WigglyWidget Class Definition


  class WigglyWidget : public QWidget
  {
      Q_OBJECT

  public:
      WigglyWidget(QWidget *parent = 0);

  public slots:
      void setText(const QString &newText) { text = newText; }

  protected:
      void paintEvent(QPaintEvent *event) override;
      void timerEvent(QTimerEvent *event) override;

  private:
      QBasicTimer timer;
      QString text;
      int step;
  };

WigglyWidget类提供了显示文本的舞动效果。我们子类化QWidget并重新实现标准的paintEvent()和timerEvent()函数来绘制和更新小部件。此外,我们实现了一个公共setText()槽,用于设置小部件的文本。

类型为QBasicTimer的计时器变量用于定期更新小部件,使小部件移动。text变量用于存储当前显示的文本,并计算波动线上每个字符的位置和颜色。

WigglyWidget Class Implementation

WigglyWidget::WigglyWidget(QWidget *parent)
      : QWidget(parent)
  {
      setBackgroundRole(QPalette::Midlight);
      setAutoFillBackground(true);

      QFont newFont = font();
      newFont.setPointSize(newFont.pointSize() + 20);
      setFont(newFont);

      step = 0;
      timer.start(60, this);
  }

在构造函数中,我们使用QPalette::Midlight color role使小部件的背景比通常的背景稍微亮一点。背景角色定义了来自小部件调色板的画笔,Qt使用它来绘制背景。然后我们将小部件的字体放大20点。

最后我们开始计时;对QBasicTimer::start()的调用确保这个特定的wiggly小部件将在计时器超时(每60毫秒)时接收生成的计时器事件。计算波动线上每个字符的位置和颜色。


  void WigglyWidget::paintEvent(QPaintEvent * /* event */)
  {
      static const int sineTable[16] = {
          0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
      };

      QFontMetrics metrics(font());
      int x = (width() - metrics.width(text)) / 2;
      int y = (height() + metrics.ascent() - metrics.descent()) / 2;
      QColor color;

每当向小部件发送update()时,就会调用paintEvent()函数。绘制事件被发送到需要更新自身的小部件,例如,当小部件的一部分因为覆盖小部件被移动而暴露时。对于wiggly小部件,还将从timerEvent()槽每60毫秒生成一个油漆事件。

sineTable表示sin曲线的y值,乘以100。它用于使波动小部件沿着正弦曲线移动。

QFontMetrics对象提供有关小部件字体的信息。变量x是我们开始绘制文本的水平位置。变量y是文本基线的垂直位置。计算这两个变量时,文本是水平和垂直居中的。为了计算基线,我们考虑了字体的上升(字体在基线之上的高度)和字体的下降(字体在基线之下的高度)。如果下降等于上升,它们相互抵消,基线的高度是()/ 2。

 QPainter painter(this);
      for (int i = 0; i < text.size(); ++i) {
          int index = (step + i) % 16;
          color.setHsv((15 - index) * 16, 255, 191);
          painter.setPen(color);
          painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400),
                           QString(text[i]));
          x += metrics.width(text[i]);
      }
  }

每次调用paintEvent()函数时,我们都创建一个QPainter对象画家来绘制小部件的内容。对于文本中的每个字符,我们根据step来确定颜色和波动线的位置。此外,x会随着角色的宽度增加。

为简单起见,我们假设QFontMetrics::width(text)返回单个字符宽度的和(QFontMetrics::width(text[i]))。实际上,情况并非总是如此,因为QFontMetrics::width(text)还考虑了某些字母(如‘A’和‘V’)之间的字距。结果是文本没有完全居中。您可以通过在编辑行中键入“avavavavav”来验证这一点。


  void WigglyWidget::timerEvent(QTimerEvent *event)
  {
      if (event->timerId() == timer.timerId()) {
          ++step;
          update();
      } else {
          QWidget::timerEvent(event);
      }

 

函数的作用是:接收为这个小部件生成的所有计时器事件。如果小部件的QBasicTimer发送了一个计时器事件,则递增步骤使文本移动,并调用QWidget::update()刷新显示。任何其他计时器事件都传递给基类的timerEvent()函数的实现。

QWidget::update()插槽不会导致立即重新绘制;当Qt返回到主事件循环时,槽调度一个paint事件进行处理。绘制事件随后由WigglyWidget的paintEvent()函数处理。

 

 

源码下载地址

https://download.csdn.net/download/yonggandess/12606972

 

你可能感兴趣的:(Qt基础)