c++ - connect()中如何获取SLOT的成员对象?

标签 c++ qt qt5 qt-signals qt5.5

我几天前开始学习 Qt (5.5),最近在使用连接函数时遇到了一些问题,特别是 SLOT 参数。我从调用 connect 函数的同一个类中调用一个成员函数,但是当 SLOT 函数被触发时,它的行为就像是在创建一个新的类对象。当我将所有内容都放在同一个类中时,它最初起作用了,但是当我尝试实现层次结构时,这个问题突然出现了。我写了一个简短的程序来演示我的问题。

main.cpp

#include <QApplication>

#include "MainWindow.h"

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);

  MainWindow QtWindow;

  QtWindow.show();

  return app.exec();
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWidget>
#include <QGridLayout>

#include "TopWidget.h"

class MainWindow : public QMainWindow
{
  Q_OBJECT
  public:
    MainWindow(QMainWindow *parent = 0);
  private:
    QWidget *mainWidget;
    QGridLayout *mainLayout;
};

#endif // MAINWINDOW_H

主窗口.cpp

#include "MainWindow.h"

MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent){

  mainWidget = new QWidget(this);
  mainLayout = new QGridLayout(mainWidget);
  setCentralWidget(mainWidget);

  TopWidget tWidget(this);

  mainLayout->addWidget(tWidget.topWidget, 0, 0);
}

TopWidget.h

#ifndef TOPWIDGET_H
#define TOPWIDGET_H

#include <stdlib.h>

#include <QWidget>
#include <QPushButton>
#include <QGridLayout>

#include <QDebug>
#include <QErrorMessage>

class TopWidget : public QWidget
{
  Q_OBJECT
  public:
    TopWidget(QWidget *parent);
    QWidget *topWidget;
  private:
    QGridLayout *wLayout;
    QPushButton *Button;

    int memVar1;
    int memVar2;
  private slots:
    void testConnect();
    //void SlotWithParams(int a, int b);
};

#endif // TOPWIDGET_H

TopWidget.cpp

#include "TopWidget.h"

TopWidget::TopWidget(QWidget *parent) : QWidget(parent){
  topWidget = new QWidget(parent);
  wLayout = new QGridLayout(topWidget);

  memVar1 = 123;
  memVar2 = 321;

  Button = new QPushButton("Click Me", topWidget);
  connect(Button, &QPushButton::clicked, [=](){ TopWidget::testConnect(); });
}

void TopWidget::testConnect(){
  qDebug("Button worked");
  if(memVar1 != 123 || memVar2 != 321){
    qDebug("Linking failed");
  }else{
    qDebug("Linking success");
  }
}

因为我刚开始使用 Qt,所以我不太清楚什么是“正确的”Qt 代码,以及我应该避免什么,所以也很感激这方面的提示。以下是 qmake 文件,如果这很重要的话。

CONFIG += c++11
CONFIG += debug
CONFIG += console

QT += widgets
QT += testlib

SOURCES += main.cpp
SOURCES += MainWindow.cpp
SOURCES += TopWidget.cpp
HEADERS += MainWindow.h
HEADERS += TopWidget.h

Release:DESTDIR = bin/Release
Release:OBJECTS_DIR = obj/Release
Release:MOC_DIR = extra/Release
Release:RCC_DIR = extra/Release
Release:UI_DIR = extra/Release

Debug:DESTDIR = bin/Debug
Debug:OBJECTS_DIR = obj/Debug
Debug:MOC_DIR = extra/Debug
Debug:RCC_DIR = extra/Debug
Debug:UI_DIR = extra/Debug

当我在 Debug模式下运行程序并按下按钮时,它输出“Button worked”表示函数链接成功,但随后输出“Linking failed”表示创建了一个新对象而不是使用旧对象一。我对 C++ 的了解是零散的,因为我只学到了我需要的东西,昨天我花了几个小时试图解决这个问题,所以请原谅我,如果修复是非常简单的事情,但我已经为此精疲力尽了。

最佳答案

问题出在这一行:

TopWidget tWidget(this);

您正在堆栈上分配 tWidget,它在 MainWindow 构造函数结束时被销毁。

替换为:

TopWidget * tWidget = new TopWidget(this);

另外,你应该用这个替换你的连接线

connect(Button, &QPushButton::clicked, this, &TopWidget::testConnect);

看起来即使在 TopWidget 被销毁后,您的插槽也会被调用。 Qt 通常会在发送方或接收方被破坏时断开连接,但当您连接到 lambda 时它无法断开连接。

最后,你在做一些奇怪的事情。您的 TopWidget 类除了创建另一个小部件并在其插槽上接收信号外还有什么用途?您永远不会将 TopWidget 添加到任何布局,而只是它的子布局。 TopWidget 从未显示,因此它应该仅派生自 QObject

关于c++ - connect()中如何获取SLOT的成员对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34088426/

相关文章:

C++/Qt - QThread 与 QRunnable

c++ - 不按住键选择多个 QGraphicsItems

python - PyQt5 中的 devicePixelRatio 损坏

c++ - 模板特化 : non-inline function definition issue

c++ - ucontext 和线程本地存储

使用 OpenGL 进行 Qt 渲染

c++ - 发送命令后串口关闭

c++ - Qt:QSqlRelationalTableModel 引用不存在的外键

c++ - 将char转换为short时如何避免0xFF前缀?

c++ - 设置我的应用程序 api 感知并防止系统使其模糊和错误定位