Qt:使用信号和插槽从另一个类调用MainWindow::Ui

Qt: Calling MainWindow::Ui from another class using signals and slots

本文关键字:另一个 调用 MainWindow Ui 插槽 信号 Qt      更新时间:2023-10-16

我做了一个简单的Qt项目来解决从另一个类调用Ui的问题

文件:
mainwindow.h|mainwindow.cpp|client.h|client.cpp|main.cpp

问题:
将信号从client.cpp连接到主窗口.cpp中的插槽效果非常好
但是当我添加一个

ui->statusBar->showMessage("message")时
在插槽中,它不起作用
注意:当我在mainwindow.cpp中创建信号和插槽时,它起作用,但从client.cpp中的信号和connect()调用mainwindow.cpp的插槽不起作用

代码:(修剪到要点)

主窗口.h

namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT

signals:
public slots:
    void doSomething();
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};


mainwindow.cpp

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

void MainWindow::doSomething()
{
    QMessageBox::information(0, "test", "BINGO!!");
    ui->statusBar->showMessage("testing");
}


client.h

class client : public QObject
{
    Q_OBJECT
public:
    explicit client(QObject *parent = 0);
    void call();
signals:
    void connected();
public slots:
};


client.cpp

client::client(QObject *parent) :
    QObject(parent)
{
    MainWindow main;
    connect(this, SIGNAL(connected()), &main, SLOT(doSomething()));
    call();
}
void client::call()
{
    emit connected();
}



添加:
main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

谢谢。

client::client(QObject *parent) :
    QObject(parent)
{
    MainWindow main;
    connect(this, SIGNAL(connected()), &main, SLOT(doSomething()));
    call();
}

您的MainWindow位于堆栈上。我认为当你的doSomething槽被触发时,MainWindow对象已经不见了。请尝试在堆上创建MainWindow。

我在您发布的代码中发现了一个重大错误。

您已经在文件main.cpp中创建了MainWindow的实例,这就是您运行应用程序时看到的窗口。但是在client.cpp中,您正在创建MainWindow的第二个实例,并将来自client对象的信号连接到您创建的第二MainWindow对象的插槽。您没有看到两个主窗口,因为您没有运行第二个实例的execshow方法。

现在进入解决方案,您必须将信号从client连接到适当的MainWindow实例。我将在下面建议两种方法。

第一个

我相信您在类MainWindow的一个成员函数中创建了client的实例。如果是,则将连接方法转移到文件mainwindow.cpp

类似于:

void MainWindow::someFunction()
{
    client* c = new client();
    connect(c, SIGNAL(connected()), this, SLOT(doSomething()));
    c->call();
}

第二个:

如果不能执行上面解释的操作,那么可以使用静态指针和静态函数的组合来获取MainWindow的实例。请注意,此方法也可用于确保在任何给定时间只有一个MainWindow实例。

主窗口.h

namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT

signals:
public slots:
    void doSomething();
public:
    explicit MainWindow(QWidget* parent = 0);
    ~MainWindow();
    static MainWindow* GetInstance(QWidget* parent = 0);
private:
    Ui::MainWindow *ui;
    static MainWindow* mainInstance;
};

主窗口.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
MainWindow* MainWindow::mainInstance = 0;
MainWindow* MainWindow::GetInstance(QWidget *parent)
{
    if(mainInstance == NULL)
    {
        mainInstance = new MainWindow(parent);
    }
    return mainInstance;
}
void MainWindow::doSomething()
{
    QMessageBox::information(0, "test", "BINGO!!");
    ui->statusBar->showMessage("testing");
}

现在,在任何需要使用MainWindow实例的类中,只需使用静态函数MainWindow::GetInstance获取指向MainWindow实例的指针,并将其用作连接的参数。即

MainWindow* instance = MainWindow::GetInstance();
client* c = new client();
connect(c, SIGNAL(connected()), instance , SLOT(doSomething()));