范围内 QTimer 在 Ubuntu 上运行但不在 Windows 上运行

In-scope QTimer runs on Ubuntu but not on Windows

我在 Windows 上遇到 QTimer 问题。

使用上下文如下:

  1. 我逐行读取一个文件,并在开始前触发一个 10 秒的计时器
  2. 如果文件在 10 秒内处理完毕,则一切正常
  3. 如果文件太大,那我不想花太多时间CPU阅读它并在 10 秒后停止甚至以为我没有读完

这是代码:

//Function readModel, with arguments path and modelType

//Check if files exists and opens it

QTimer readPointsTimer;
readPointsTimer.setInterval(10000);
readPointsTimer.setSingleShot(true);
readPointsTimer.start();

in.seek(0); //The file is already opened if it exists
while (!in.atEnd() && m_process){ //While I did not reach the end of the file, or the user didn't ask to stop
    qDebug() << "remaining" << readPointsTimer.remainingTime();
    if(readPointsTimer.remainingTime()==0 && m_readPoints){
        m_process = false;
        m_fileReadEntirely = false;
        readCommentsTimer.start();
    }

    //Read line
    QString line = in.readLine();
    //Some process function not important for this post
}
readPointsTimer.stop();
//Some finalization not important for this post

我遇到的问题如下:在 Ubuntu 这段代码中 运行 很好 。计时器被触发并且 qDebug() 显示倒计时。当它达到 0 时,while 循环将按预期停止。 在 windows 上,情况有所不同。 qDebug() 始终显示“10000”,因为计时器已启动但未倒计时。

为了提供更多上下文,此函数在并发线程中被触发到 运行:

void ModelManager::loadModel(ModelManager::MODEL_TYPE type, const QString &path)
{
    m_loadingFuture = QtConcurrent::run(this,&ModelManager::readModel, type, path);
}

您知道什么会导致 Windows 出现这种行为吗?即使是 Ubuntu 的函数编码也很糟糕,还是 Windows 的一些特殊性? 提前谢谢你

在没有检验该假设的情况下,我认为写入屏幕通常需要相当长的时间可能是个问题;为了改善这一点,通常对其进行缓冲;这意味着当你执行 qDebug() << "remaining" << readPointsTimer.remainingTime(); 时,你实际上并没有直接写入屏幕,而是写入了一些内部缓冲区,然后偶尔刷新它(但这样做需要一些时间)。但是所有这一切都是在它仍然再次填充缓冲区的时候;你写 qDebug 每个循环周期,所以文件的每一行,这意味着你可以写它数百万次......

为了防止输出缓冲区不堪重负(通常是为了避免不必要的过量输出),我会减少输出的频率,比如每秒一次:

QElapsedTimer t;
t.start();
while (!in.atEnd() && m_process){ //While I did not reach the end of the file, or the user didn't ask to stop
    if (t.elapsed() > 1000)
    {
        qDebug() << "remaining" << readPointsTimer.remainingTime();
        t.start();
    }
    // ...
}

当您这样做时,您甚至可以将 QTimer 完全替换为更简单的 QElapsedTimer。 您实际上似乎不需要 QTimer - 它的主要功能是定期或“完成”时启动某些功能。当前显示的所有代码都使用 QTimer 来测量自开始读取文件以来经过的时间(通过查询 remainingTime())。