【问题标题】:processEvents And Memory Leak?进程事件和内存泄漏?
【发布时间】:2009-08-24 06:39:28
【问题描述】:

注意:提供的代码只是给出了应用程序结构的想法

我有一个 Qt 应用程序,与外部硬件接口。该结构使得与硬件接口的类继承自QObject,并与主GUI线程类组成。假设这个类是 test.h,下面是它的示例代码:

#ifndef TEST_H
#define TEST_H

#include <QLineEdit>
#include <QString>
#include <QTimer>
#include "ui_test.h"

#define TIMEOUT 100
class TestObj;
class TestApp:public QWidget, public Ui::mTestForm
{
    Q_OBJECT

public:
    TestApp(QWidget* parent=0);
    QTimer* mTimer;
    bool mWindowClosed;
    TestObj* mObj;

public slots:
    void UpdateText();
    void Exit();
};

class TestObj:public QObject
{
    Q_OBJECT
public:
    TestObj();
    void RandomTest();
};
#endif

test.cpp 的代码是

#include "test.h"

TestApp::TestApp(QWidget* parent):QWidget(parent)
{
    setupUi(this);
    mObj = new TestObj();
    mWindowClosed=false;
    mLineEdit->setText("Hello");
    mTimer=new QTimer();
    mTimer->singleShot(1000,this,SLOT(UpdateText()));
    connect(mExitButton,SIGNAL(clicked()),this, SLOT(Exit()));
}

void TestApp::UpdateText()
{
    if(mWindowClosed)
    {
    //QApplication::processEvents();
        return;
    }
    else
    {
    //QApplication::processEvents();
        mObj->RandomTest();
        mLineEdit->setText("Hi");
        mTimer->singleShot(100,this,SLOT(UpdateText()));
    }
}

void TestApp::Exit()
{
    mWindowClosed=true;
}

现在考虑TestObj 类是用于与硬件接口的类。这个类向硬件发送三个可能的命令(在实际代码中,上面只是一个示例结构),具有不同的超时时间,因此我们有一个定时器,用于向硬件发送命令(实现为函数)。其中每一个都有一个processEvents 条目,用于识别同时对变量的任何更改。

问题是这个模块负责程序执行期间内存的稳定增长。

当我在 TestApp 构造函数中注释掉 UpdateText() 函数时,应用程序运行良好。

我的猜测是,由于发生了很多 GUI 事件,因此很可能存在信号槽排队,从而导致内存增加。而且由于该类没有实现为单独的线程并与主 GUI 线程结合在一起。主线程不断更新。

有人可以建议出路吗?我无权更改设计,否则我会将接口类实现为线程。因此,如果可以按照当前设计提出解决方案,那将是有益的。

【问题讨论】:

  • 您为什么担心它会因为重复而被关闭?既然你这么说,我几乎想去寻找所有其他问题,看看这个是否真的不是重复的......
  • 因为它仍然是我认为最常见的内存泄漏:您确定在更新字符串时删除了所有字符串?更准确地说:您是否在设置新字符串之前删除了旧字符串? (如有必要)。不过,不要认为那是真正的问题,所以我只是评论:)。

标签: c++ linux qt


【解决方案1】:

创建一个常规计时器,将其间隔设置为 100,并将其 timout 信号连接到 UpdateText 函数将避免事件堆积。

P.S:singleShot不需要QTimer对象,可以直接调用QTimer::singleShot

【讨论】:

  • 感谢您考虑我的问题,但这与 QTimer 对象无关。
【解决方案2】:

猜测:

尝试改变这个:

mTimer->singleShot(100,this,SLOT(UpdateText()));

到这里:

if (!slotSet) 
{
    mTimer->singleShot(100,this,SLOT(UpdateText()));
    slotSet = true;
}

【讨论】:

  • 这无法完成,因为我必须不断向硬件发送命令
猜你喜欢
  • 2011-01-13
  • 1970-01-01
  • 2018-11-12
  • 2012-05-31
  • 2014-11-08
  • 1970-01-01
  • 2019-02-17
  • 2017-12-21
  • 2013-11-05
相关资源
最近更新 更多