返回介绍

定时器

发布于 2019-10-04 15:05:01 字数 2327 浏览 937 评论 0 收藏 0

在Qt中,QObject,所有Qt对象的基类,提供了一个基本的定时器。通过QObject::startTimer(),你可以把一个以毫秒为单位的时间间隔作为参数来开始定时器。这个函数返回一个唯一的整数的定时器的标识符。这个定时器现在就会在每一个时间间隔“触发”,直到你明确地使用这个定时器的标识符来调用QObject::killTimer()结束。

对于这种工作机制,应用程序不得不在一个事件回路中运行。你通过QApplication::exec()来开始一个事件回路。当定时器触发时,应用程序会发送一个QTimerEvent,并且控制流直到定时器事件被处理时才会离开事件回路。这暗示着当你的应用程序正忙于其它事情的时候,定时器不能触发。换句话说,定时器的精确性依赖于你的应用程序的间隔尺度。

事实上,对于间隔值是没有上限的(超过一年也是可能的)。精确性依赖于位于下面的操作系统。Windows 95/98的精确度为55毫秒(每秒18.2次),其它我们已经测试过的操作系统(UNIX X11、Windows NT和OS/2)都可以处理1毫秒的间隔。

定时器功能的主要的应用程序接口是QTimer。这个类可以提供当定时器触发的时候发射一个信号的有规律的定时器,并且继承了QObject,所以它很适合绝大多数图形用户界面程序的所有权结构。通常的使用方法如下:

    QTimer * counter = new QTimer( this );
    connect( counter, SIGNAL(timeout()),
             this, SLOT(updateCaption()) );
    counter->start( 1000 );

counter定时器被作为这个窗口部件的子类,这样当这个窗口部件被删除时,定时器也会被删除。接下来,它的timeout信号被连接到将要做工作的槽上,最后它开始了。

QTimer也提供了一个简单的只有一次定时器的应用程序接口。QButton,当键盘被用来“按下”按钮的时候,在按钮被按下来显示按钮和接下来(0.1秒之后)被释放时使用它来显示按钮,例如:

    QTimer::singleShot( 100, this, SLOT(animateTimeout()) );

在这行代码之后0.1秒时,同一个按钮的animateTimeout()槽被调用。

这里是一个通过QTimer对象的信号和槽来进行对象通讯的不太复杂的实例的大纲。它示范了一个单线程应用程序如何使用定时器在不阻塞用户界面的情况下进行精确运算的。

	// Mandelbrot类使用QTimer在不阻塞CPU的情况下来计算一个扫描行。
	// 它继承了QObject来使用信号和槽。调用start()来开始运算。当运
	// 算完成时,done()信号被发射。注意这个例子并不完全,只是一个
	// 大纲。

    class Mandelbrot : public QObject
    {
        Q_OBJECT // 因为需要使用信号/槽
    public:
        Mandelbrot( QObject *parent=0, const char *name );
        ...
    public slots:
        void start();
    signals:
        void done();
    private slots:
        void calculate();
        private:
        QTimer timer;
        ...
    };

    //
    // 构造并初始化Mandelbrot对象。
    //

    Mandelbrot::Mandelbrot( QObject *parent=0, const char *name )
    : QObject( parent, name )
    {
        connect( &timer, SIGNAL(timeout()), SLOT(calculate()) );
        ...
    }

    //
    // 开始运算任务。内部的calculate()槽会每10毫秒被激活一次。
    //

    void Mandelbrot::start()
    {
        if ( !timer.isActive() ) // 还没有准备好运行
            timer.start( 10 );   // 每10毫秒超时
    }

    //
    // 每次运算一个扫描行。
    // 当结束时发射done()信号。
    //

    void Mandelbrot::calculate()
    {
        ...                // 执行一个扫描行的运算
        if ( finished ) {  // 没有更多的扫描行了
            timer.stop();
            emit done();
        }
    }
  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文