关于QT 计时器的问题,求大神指导。

apuded 2015-01-19 01:19:49



状态栏上放一个计时器,有一个textEdit,在textEdit中输入内容可以触发计时器,
问题来了,在textEdit中不断输入内容(或者不断复制粘贴)会导致计时器计时变慢(停止),
如果改为由button触发,问题也是一样的。不知道是什么问题。求大神指导。
源码地址:
http://pan.baidu.com/s/1mgkOB3M

main.cpp/
#include "mainwindow.h"
#include <QApplication>
#include <mainwindow.cpp>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;

// w.StartStopwatch();

w.show();

return a.exec();
}



mainwindow.cpp/
#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
textEdit = new QTextEdit("问题:在这框中不断输入内容(或者不断复制粘贴)会导致计时器计时变慢(停止)",this);

button = new QPushButton("开始",this);
label = new QLabel("时间:00:00:00",this);

layout = new QVBoxLayout();
layout->addWidget(textEdit);
layout->addWidget(button);


widget = new QWidget();
widget->setLayout(layout);
this->setCentralWidget(widget);

statusBar()->show();
statusBar()->setStyleSheet("background:white");
ui->statusBar->addWidget(label,1);





countTemp=0;
secondTemp=0;
minuteTemp=0;
hourTemp=0;






msTimer= new QTimer;


connect(msTimer,SIGNAL(timeout()),this,SLOT(TimeSlot()));
connect(button,SIGNAL(clicked()),this,SLOT(Start()));
connect(textEdit,SIGNAL(textChanged()),this,SLOT(Start()));




}





void MainWindow::TimeSlot()
{
countTemp+=1;
if(countTemp==100)
{
countTemp=0;
secondTemp+=1;
if(secondTemp==60)
{
secondTemp=0;
minuteTemp+=1;
if(minuteTemp==60)
{
minuteTemp=0;
hourTemp+=1;
if(hourTemp==24)
{
hourTemp=0;
}
}
}
}
//把整数转换成字符串
QString hourstr = QString::number(hourTemp);
QString minutestr= QString::number(minuteTemp);
QString secondstr = QString::number(secondTemp);
//设置字符串的长度为2
SetStrLength(&hourstr,2);
SetStrLength(&minutestr,2);
SetStrLength(&secondstr,2);
Display(hourstr + ":",minutestr + ":",secondstr);
}



void MainWindow::Display(QString hour, QString minute, QString second)
{



label->setText("时间:"+hour+minute+second);

}





void MainWindow::StartStopwatch()
{
msTimer->start(10); //10ms



}


void MainWindow::SetStrLength(QString *str, int length)
{
if(str->length()<length)
{
str->insert(0,"0");
}
}




void MainWindow::Start()
{
StartStopwatch();
}





MainWindow::~MainWindow()
{
delete ui;
}


mainwindow.h/
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextEdit>
#include <QVBoxLayout>
#include <QWidget>
#include <QLabel>
#include <QTimer>
#include <QPushButton>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void StartStopwatch();



private:
Ui::MainWindow *ui;

QTextEdit *textEdit;
QVBoxLayout * layout;
QWidget * widget;
QLabel * label;

QPushButton *button;

int hourTemp;
int minuteTemp;
int secondTemp;
int countTemp;


QTimer *msTimer;




void Display(QString,QString,QString);
void SetStrLength(QString *str, int length);
private slots:
void TimeSlot();
void Start();





};

#endif // MAINWINDOW_H

...全文
432 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
apuded 2015-01-20
  • 打赏
  • 举报
回复
引用 15 楼 n7zj0x8 的回复:
谢邀,代码已经修改,主要方法是把Timer移入到一个单独的线程. 代码在这里.我写了注释的. http://pan.baidu.com/s/1yaqV8
试了下,真的可以。真的非常感谢 !层主好人,帮了我大忙。 上次向你请教的richtext的问题:http://bbs.csdn.net/topics/390972843 我试了下,用QTextDocument还是有问题,会卡顿,大神能否一并帮我改改? 衷心感谢!
大卫无限 2015-01-20
  • 打赏
  • 举报
回复
谢邀,代码已经修改,主要方法是把Timer移入到一个单独的线程. 代码在这里.我写了注释的. http://pan.baidu.com/s/1yaqV8
apuded 2015-01-19
  • 打赏
  • 举报
回复
自顶自顶自顶自顶
apuded 2015-01-19
  • 打赏
  • 举报
回复
引用 11 楼 feiyangqingyun 的回复:
没有这回事,代码有误!
那错误在哪里呢大神
feiyangqingyun 2015-01-19
  • 打赏
  • 举报
回复
没有这回事,代码有误!
apuded 2015-01-19
  • 打赏
  • 举报
回复
引用 9 楼 cuzn1024 的回复:
首先,textedit和button触发timer的start函数,虽然都是如你所说的变慢,但实际上各自原因不同。textedit触发是因为你多次调用了start函数,相当于key一次都让定时器重新开始计时,必然是看起来很慢的。button触发计时器只会一次开始,但是你频繁的textedit输入会使消息循环不停被key事件占据,导致其他事件处理不及时。 其次,时间字符串有现成函数可以用的,QTime::toString()有格式化参数的。
大神,你懂得很多,求给个解决方法吧。难道只能通过QTime计时吗。百度了下说 只需要一个QTime实例,让它start,然后调用elapsed就能得到从start之后过去的毫秒值。求给点代码提示。谢谢。
  • 打赏
  • 举报
回复
首先,textedit和button触发timer的start函数,虽然都是如你所说的变慢,但实际上各自原因不同。textedit触发是因为你多次调用了start函数,相当于key一次都让定时器重新开始计时,必然是看起来很慢的。button触发计时器只会一次开始,但是你频繁的textedit输入会使消息循环不停被key事件占据,导致其他事件处理不及时。 其次,时间字符串有现成函数可以用的,QTime::toString()有格式化参数的。
apuded 2015-01-19
  • 打赏
  • 举报
回复
引用 7 楼 sddsighhz 的回复:
[quote=引用 5 楼 apuded 的回复:] 大神。有没有解决方法。通过textEdit触发计时器,不断输入内容,计时器能正常运行。
为什么要用textEdit去触发计时器? QTimer调用start后就已经在跑了,不用多次调用start。计时的话你可以用QTime[/quote] 如果不用textEdit触发,按钮触发也一样的,textEdit明明和这个QTimer无关,在textEdit不断输入,也会影响到计时。 但是如果直接在main.cpp中w.StartStopwatch(); 程序一运行就开始计时,这时在textEdit中不断输入就不会影响了。很纳闷。
Creator_莫言 2015-01-19
  • 打赏
  • 举报
回复
引用 5 楼 apuded 的回复:
大神。有没有解决方法。通过textEdit触发计时器,不断输入内容,计时器能正常运行。
为什么要用textEdit去触发计时器? QTimer调用start后就已经在跑了,不用多次调用start。计时的话你可以用QTime
apuded 2015-01-19
  • 打赏
  • 举报
回复
引用 3 楼 dbzhang800 的回复:
QTimer不是干这个用的。 首先,它没有精度保证,20ms的精度都没有。再就是timer事件会合并,比如2个或几个合在一块,可能1s或2s你才收到1个timeout信号
大神,求个解决方法,计时器不用QTimer那应该怎么实现。网上资料挺少的。求告知。谢谢。
apuded 2015-01-19
  • 打赏
  • 举报
回复
引用 4 楼 sddsighhz 的回复:
void QTimer::start(int msec) [slot] Starts or restarts the timer with a timeout interval of msec milliseconds. If the timer is already running, it will be stopped and restarted. 文档说的很明显,当你不断输入的时候就会不断调用start函数,计时器就会停止然后重新开始,可不就变慢了吗
大神。有没有解决方法。通过textEdit触发计时器,不断输入内容,计时器能正常运行。
Creator_莫言 2015-01-19
  • 打赏
  • 举报
回复
void QTimer::start(int msec) [slot] Starts or restarts the timer with a timeout interval of msec milliseconds. If the timer is already running, it will be stopped and restarted. 文档说的很明显,当你不断输入的时候就会不断调用start函数,计时器就会停止然后重新开始,可不就变慢了吗
dbzhang800 2015-01-19
  • 打赏
  • 举报
回复
QTimer不是干这个用的。 首先,它没有精度保证,20ms的精度都没有。再就是timer事件会合并,比如2个或几个合在一块,可能1s或2s你才收到1个timeout信号
apuded 2015-01-19
  • 打赏
  • 举报
回复
自己顶吧求大神
apuded 2015-01-19
  • 打赏
  • 举报
回复
自顶顶顶顶顶

16,238

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧