如何在 QThread 中运行计时器?

2023-11-23

我想在 QThread 内运行一个计时器。我编写了一些代码,在运行时出现一些错误。我究竟做错了什么?

(父级是QThread(0x1498d10),父级线程是QThread(0x11272b0),当前线程是QThread(0x1498d10)

主 .h 文件,*mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "mythread.h"
namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
        MyThread *myt;

    private:
        Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

主 .cpp 文件,mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    myt = new MyThread();
    myt->start();
    MainWindow w;
}

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

线程、文件类线程.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QTimer>

class MyThread:public QThread
{
    public:
        MyThread();
        void run();
        QTimer *thr;

    public slots:
        void slo();
};

#endif // MYTHREAD_H

File mythread.cpp

#include "mythread.h"

MyThread::MyThread()
{
    thr = new QTimer();
    connect(thr, SIGNAL(timeout()), this, SLOT(slo()));
}

void MyThread::run()
{
    thr->start(1000);
}

void MyThread::slo()
{
    int i, j = 0;
    i = i + j;
}

只是我的拙见:不要子类化 QThread当你不需要的时候就不再这样做了。

我认为您只想在新线程中运行您的类,或更可能您不想阻止其他任务。你的类不是线程本身。子类化基本上意味着你的类is你正在子类化什么。

换句话说:让 QThread 做好它的工作,集中精力让你的类做它应该做的事情。

Example:MyClass 本身对线程一无所知。它只是做它必须做的事情。增加一个值并显示结果(加上一些睡眠部分以显示它如何阻止其他功能或 GUI)

头文件

#include <QTimer>
#include <QObject>

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(bool willSleep, QString name, QObject *parent = 0);
public slots:
    void updateCount();
private:
    QTimer *timer;
    int count;
    bool m_wantToSleep;

};

执行

#include "myclass.h"
#include <QDebug>

MyClass::MyClass(bool wantToSleep, QString name, QObject *parent) :
    QObject(parent)
{
    this->setObjectName(name);
    m_wantToSleep = wantToSleep;
    count = 0;
    timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(updateCount()));
    timer->start(100);
}

void MyClass::updateCount()
{
    ++count;
    qDebug() << objectName() << " count: " << count;
    if (m_wantToSleep)
        sleep(1);
}

我们有可以完成这项工作的代码。

现在实现更多线程。非常简单(内存管理等就不处理了,有一个简单的例子)

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QThread>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QThread *thread1 = new QThread; // First thread
    QThread *thread2 = new QThread; // Second thread

    thread1->start();
    thread2->start();

    MyClass *myClass = new MyClass(false, "normal class");
    MyClass *mySleepClass = new MyClass(true, "sleeper class");

    // Better to implement a start slot to start the timer (not implemented)
    // connect(thread1, SIGNAL(started), myClass, SLOT(start()));
    // but this suffices, because the timer will emit the first signal after the class is moved to another thread
    //mySleepClass->moveToThread(thread1);
    //myClass->moveToThread(thread1);
}

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

现在我们可以使用线程了:

阻止 GUI(当然我们不希望这样)

最初的示例无需使用新线程即可工作。对象位于当前线程中,这就是 GUI 被阻塞的原因(因为我在一个实例中使用了 sleep 函数)。

//mySleepClass->moveToThread(thread1);
//myClass->moveToThread(thread1);

非阻塞图形用户界面

我们还有两个线程正在运行。为什么不使用它们呢?在示例中,QThreads 已经在运行,但它们什么也没玩。让我们将实例移到那里,以确保 GUI 所在的主循环不会再被阻塞。

神奇的功能是移动到线程

取消注释行,您可以看到 GUI 不会被阻止。两个实例都在新线程中。但话又说回来,有一个睡眠功能,所以一个人应该比另一个人计数得更快。但事实并非如此。因为他们互相阻碍。它们在同一个线程中。

mySleepClass->moveToThread(thread1);
myClass->moveToThread(thread1);

前面两种情况的结果应该是:(实例位于同一线程中并共享相同的事件循环,因此它们相互阻塞)

"normal class"  count:  1
"sleeper class"  count:  1
"normal class"  count:  2
"sleeper class"  count:  2
"normal class"  count:  3
"sleeper class"  count:  3

所以将它们移动到一个单独的线程

现在 GUI 不再被阻止;两者都不是彼此的实例。

mySleepClass->moveToThread(thread1);
myClass->moveToThread(thread2);

结果应该是(并且 GUI 不应该被阻止):

"sleeper class"  count:  1
"normal class"  count:  1
"normal class"  count:  2
"normal class"  count:  3
"normal class"  count:  4
"normal class"  count:  5

我希望这是可以理解的。对我来说,这是比子类化更合乎逻辑的方法。

当然你可以在你的MyClass中创建一个QThread实例。没有必要在 MyClass 之外创建它,我只是想表明您可以创建一个线程并在那里移动更多实例。

对于那些不同意的人,我只想说:MyClass 是一个支持线程的计数器听起来比:MyClass是一个具有计数器能力的线程 :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 QThread 中运行计时器? 的相关文章

  • 在 xaml 中编写嵌套类型时出现设计时错误

    我创建了一个用户控件 它接受枚举类型并将该枚举的值分配给该用户控件中的 ComboBox 控件 很简单 我在数据模板中使用此用户控件 当出现嵌套类型时 问题就来了 我使用这个符号来指定 EnumType x Type myNamespace
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • C++ 中的 include 和 using 命名空间

    用于使用cout 我需要指定两者 include
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现

随机推荐