【问题标题】:How to deal with signal and slot in different classes in QtQt中如何处理不同类中的信号和槽
【发布时间】:2021-05-21 15:35:21
【问题描述】:

我的用户界面如下图所示: 在MainWindow里面,有一个很大的红色QStackedWidget区域,我将用来放置不同的自定义stackedwidgets,当前StackedWidget1有三个CardWidgets,(StackedWidget和CardWidget都是cpp类),每个CardWidget里面都有一个按钮,我想做的事当我点击 CardWidget 的按钮时,CardWidget 向 MainWindow 发送信号,MainWindow 然后从当前的stackedwidget 切换到另一个自定义的stackedwidget,同时,信号将cardwidget 中的一些变量携带到新的自定义stackedwidget。

现在的问题是,当我单击一个按钮后,cardwidget1 发出信号,主窗口中的插槽功能没有反应。 我搜索了一个与我的情况类似的问题,link,也许正如 Eeli K 和 dheerendra 所说,这里 mainwindow.cpp 中 connect(...) 中使用的 cardwidget-sender 实例与中的 cardwidget-sender 实例不同StackedWidget1.cpp,所以主窗口实际上没有收到信号。

另外,我在 mainwindow.cpp 中构造了没有任何参数的 cardwidget-sender 实例,但我在 StackedWidget1.cpp 中构造了带有 5 个参数的 cardwidget-sender 实例。

我编写了一个最小的、可重现的示例 Qt 项目 - download link

对于那些想直接看代码的人,我提取了它的一些代码:

# mainwindow.cpp
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    stackedwidget1 = new StackedWidget1(ui->stackedWidget);
    ui->stackedWidget->addWidget(stackedwidget1);

    CardWidget* card = new CardWidget();
    bool c_res = connect (card, &CardWidget::open_panel_signal, this, &MainWindow::open_panel);
    qDebug()<<"Connect open_panels signal and slot ? :"<<c_res;

    //If i emit signal from here instead of from cardwidget, it can trigger the slot function, uncomment to see it
//    int dummy_int = 0;
//    QString dummy_string = "abcd";
//    emit card->open_panel_signal(dummy_int, dummy_string);
}

void MainWindow::open_panel(int index, QString text)
{
    qDebug()<<"test text from cardwidget"<<index<<"is"<<text;
    stackedwidget2 = new StackedWidget2(ui->stackedWidget);
    ui->stackedWidget->addWidget(stackedwidget2);
    ui->stackedWidget->setCurrentWidget(stackedwidget2);
}

#mainwindow.h
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

public slots:
    void open_panel(int index, QString text);

private:
    Ui::MainWindow *ui;
    StackedWidget1* stackedwidget1;
    StackedWidget2* stackedwidget2;
};

# stackedwidget1.cpp
StackedWidget1::StackedWidget1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StackedWidget1)
{
    ui->setupUi(this);
    for(int col = 0; col< 3; col++){
        CardWidget* card = new CardWidget(this,col);
        ui->tableWidget->setCellWidget(0, col, card);
        ui->tableWidget->update();
    }
}

# cardwidget.cpp
CardWidget::CardWidget(QWidget *parent, int index) :
    QWidget(parent),
    ui(new Ui::CardWidget),
    index_(index)
{
    ui->setupUi(this);
}

void CardWidget::on_pushButton_clicked()
{
    QString text = "text from cardwidget";
    emit open_panel_signal(index_, text);
    qDebug()<<"emit signal from cardwidget"<<index_;
}

# cardwidget.h
class CardWidget : public QWidget
{
     Q_OBJECT

public:
    explicit CardWidget(QWidget *parent = nullptr, int index = 0);
    ~CardWidget();

signals:
    void open_panel_signal(int, QString);

private slots:
    void on_pushButton_clicked();

private:
    Ui::CardWidget *ui;
    int index_;
};

# stackedwidget2.cpp
StackedWidget2::StackedWidget2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StackedWidget2)
{
    ui->setupUi(this);
}

有什么好的方法可以解决这个问题吗?提前致谢!

【问题讨论】:

  • 请提供minimal, reproducible example,而不是仅仅描述您的代码。
  • 好的,明天早上我会做一个可重现的最小例子,我的时区是午夜~
  • 熬夜写出来了,请看上面的链接~
  • 您是否可以在此处发布您的代码,而不是链接到某些外部下载站点?理想情况下,示例应该小而简单,用最少的代码来解决问题。
  • 已添加,请查看。

标签: qt


【解决方案1】:

基本思路应该是:

信号(卡片小部件)-> 信号(stackedwidget1)-> SLOT(主窗口)

您可以按照一般方法:

主窗口.h

public slots:
    void open_panel(int, QString);

cardwidget.h

signals:
    void open_panel_signal(int, QString);

cardwidget.cpp

void CardWidget::on_pushButton_clicked()
{
    QString text = "text from cardwidget";
    emit open_panel_signal(index_, text);
    qDebug()<<"emit signal from cardwidget"<<index_;
}

stackedwidget1.h

signals:
    void open_panel_signal(int, QString);

stackedwidget1.cpp

StackedWidget1::StackedWidget1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StackedWidget1)
{
    ui->setupUi(this);
    for(int col = 0; col< 3; col++){
        CardWidget* card = new CardWidget(this,col);
        ui->tableWidget->setCellWidget(0, col, card);
        ui->tableWidget->update();
        connect(card,SIGNAL(open_panel_signal(int, QString)),this,SIGNAL(open_panel_signal(int, QString)));
    }
}

主窗口.cpp

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    stackedwidget1 = new StackedWidget1(ui->stackedWidget);
    ui->stackedWidget->addWidget(stackedwidget1);

    connect(stackedwidget1,SIGNAL(open_panel_signal(int, QString)),this,SLOT(open_panel(int, QString)));

    
}

【讨论】:

  • 哇,它成功了!所以我不能懒惰地跳过中产阶级——stackedwidget1。用信号连接信号也让我大开眼界。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多