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

时间:2014-09-27 20:10:32

标签: c++ qt

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

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

问题:
将来自 client.cpp 的信号连接到 mainwindow.cpp 中的插槽,效果非常好。
但是当我添加了

ui->statusBar->showMessage("message");
在插槽中,它没有工作。
注意:当我在 mainwindow.cpp 中创建信号和插槽时,它可以正常工作,但是从信号和 connect()调用来自 mainwindow.cpp 的插槽 client.cpp 中的无法正常工作。

代码:(修剪为必需品)

mainwindow.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();
}

感谢。

2 个答案:

答案 0 :(得分:1)

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

你的MainWindow生活在堆栈中。我想当你的doSomething槽被触发时,MainWindow对象已经很久了。尝试在堆上创建MainWindow。

答案 1 :(得分:0)

我发现您发布的代码存在重大错误。

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

现在进入解决方案,您必须将client的信号连接到正确的MainWindow实例。我将在下面提出两种方法。

第一

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

类似的东西:

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

第二

如果您无法执行上述操作,则可以使用静态指针和静态函数的组合来获取MainWindow的实例。请注意,此方法还可用于确保在任何给定时间只有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;

};

mainwindow.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实例的指针,并将其用作connect的参数。 即,

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