【Qt】因为槽函数问题或者逻辑问题导致重复new问题解决办法及建议

[toc]

槽函数中重复 new

这个问题比骄常见,举一个简单的例子:

1
2
3
4
5
6
7
8
connect(timer, &QTimer::timeout, this, &this::slotCreateItem);

void slotCreateItem()
{
QWidget *widget = new QWidget();
}

timer->start(1000);

上边只是为了说明一下类似的这种情况,由于一些特殊原因导致的槽函数中会多次触发 new 操作。

解决办法

  1. 设置为成员变量,在进入函数时,先执行 delete ,再去 new

    1
    2
    3
    4
    5
    6
    7
    8
    9
    void slotCreateItem()
    {
    if(nullptr == m_widget)
    {
    delete m_widget;
    m_widget = nullptr;
    }
    m_widget = new QWidget();
    }
  2. 第二种办法就是设置控件属性

    1
    2
    3
    4
    5
    void slotCreateItem()
    {
    QWidget *widget = new QWidget();
    widget->setAttribute(WA_DeleteOnClose);
    }

槽函数多次绑定问题

1
2
3
4
5
6
connect(timer, &QTimer::timeout, this, &this::slotCreateItem);

void slotCreateItem()
{
connect(timer, &QTimer::timeout, this, &this::slotRePaint); // 每进入一次就会绑定一次,每绑定一次,触发次数就会增加一次
}

解决办法

使用 Qt 的第五个参数控制。将上述代码改为以下形式

1
connect(timer, &QTimer::timeout, this, &this::slotRePaint, Qt::UniqueConnection); // (modify)每进入一次就会绑定一次,每绑定一次,触发次数就会增加一次

Qt::UniqueConnection:这是一个标记,可以使用位或与上述任何一种连接类型结合使用。当 Qt::UniqueConnection 被设置后,如果连接已经存在,QObject::connect() 将会失败(即,如果相同的信号已经为同一对对象连接到相同的槽位)。这个标志是在Qt 4.6中引入的。

以下为 Qt 第五个参数各个含义:

常量 描述
Qt::AutoConnection 0 (默认)如果接收器位于发出信号的线程中,则使用Qt::DirectConnection。否则,使用Qt::QueuedConnection。连接类型是在信号发出时确定的。
Qt::DirectConnection 1 发出信号时立即调用插槽。槽在信令线程中执行。
Qt::QueuedConnection 2 当控制返回到接收方线程的事件循环时,将调用插槽。插槽在接收方的线程中执行。
Qt::BlockingQueuedConnection 3 与Qt::QueuedConnection相同,除了信令线程阻塞直到插槽返回。如果接收端位于信令线程中,则绝不能使用此连接,否则应用程序将死锁。
Qt::UniqueConnection 0x80 这是一个标记,可以使用位或与上述任何一种连接类型结合使用。当Qt::UniqueConnection被设置后,如果连接已经存在,QObject::connect()将会失败

【Qt】因为槽函数问题或者逻辑问题导致重复new问题解决办法及建议
https://hodlyounger.github.io/B_Code/Qt/内存/【Qt】重复new问题/
作者
mingming
发布于
2023年10月27日
许可协议