来自另一个类的 Qt c++ GUI 调用

Posted

技术标签:

【中文标题】来自另一个类的 Qt c++ GUI 调用【英文标题】:Qt c++ GUI call from another class 【发布时间】:2013-07-03 13:59:21 【问题描述】:

我通过 gui 拖放创建了一个按钮和一个文本浏览器。 ui 是在 mainwindow.cpp 以及单击按钮功能中创建的。有一个 main.cpp 但这无关紧要,因为在单击开始按钮之前程序不会启动。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myserver.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

    ui->setupUi(this);


MainWindow::~MainWindow()

    delete ui;


void MainWindow::on_startButton_clicked()

    MyServer mServer;

到目前为止一切都很好,问题出在 myServer.cpp 中,我想通过 ui->textBrowser->append("hello hello"); 在 textBrowser 中写入一些内容。但是 myServer.cpp 类不“知道”用户界面。 "ui" not declared identifier

#include "myserver.h"
#include "mainwindow.h"


MyServer::MyServer(QObject *parent) :
    QObject(parent)



void MyServer::newConnection()

    server = new QTcpServer(this);

    connect(server,SIGNAL(newConnection()),this,SLOT(newConnection()));

    int ports = MainWindow::port();
    if(!server->listen(QHostAddress::Any,ports))
    

    
    else
    
        //here is the problem
        ui->textBrowser->append("hallo hallo");
    

通常我会创建一个新的(例如) MainWindow test; 并通过此 test.function(); 调用函数 但这在这里不起作用?

【问题讨论】:

【参考方案1】:

首先,当您在 MainWindow::on_StartButtonClicked 函数中创建 MyServer 对象时,需要动态创建该对象,否则它将超出范围并被删除,但也许您只是展示了这个,而不是比它在 MainWindow 标头中的声明。

至于您的问题,您的 UI 已连接到 MainWindow,因此使用 Qt 的信号和插槽将来自 MyServer 对象的信号连接到 MainWindow 并将要显示的文本发送给它。然后 MainWindow 可以将它添加到 textBrowser。像这样的东西:-

void MainWindow::on_startButton_clicked()

    MyServer* mServer = new MyServer;
    connect(mServer SIGNAL(updateUI(const QString)), this, SLOT(AppendToBrowser(const QString)));

然后代替调用 ui->textBrowser->append("hallo hallo");在 newConnection 中,发出信号:-

emit updateUI("hallo hallo");

在 MainWindow 中,您将拥有 AppendToBrowser 函数:-

void MainWindow::AppendToBrowser(const QString text)

    ui->textBrowser->append(text);

或者,您可以将 UI 对象的指针传递给 MyServer 并从那里调用它,但信号和插槽方法更简洁。

=========== 已编辑标题,以响应 cmets ======================

//Skeleton My Server header

class MyServer : public QObject

    QOBJECT

    signals:
         void updateUI(const QString text);
;

// 骨架主窗口标题

class MainWindow : public QMainWindow

    private slots:
        void AppendToBrowser(const QString text);
;

【讨论】:

所以我需要添加 'void AppendToBrowser(const QString text);'到 mainwindow.h 和 'void updateUI(const QString);'到 myserver.h ??我必须在哪个状态下设置 em? (公共,公共插槽,私人,..)我有点挣扎于差异。无论如何感谢您的帮助! 通常,Signals调用槽,所以将updateUI信号作为信号添加到myServer头中,槽函数AppendToBrowser添加到私有槽下的MainWindow头中,并在其cpp中实现。 请注意,虽然插槽与信号一起使用,但本质上它们只是函数,所以我建议使用私有插槽的原因是为了防止将 AppendToBrowser 暴露给直接从类外部调用,但例外使用插槽/信号系统。 不应该用文字代替“你好,你好”吗? MainWindow::AppendToBrowser(const QString text) ui->textBrowser->append("hallo hallo"); 是的,很明显,我的“故意错误”——老实说!在答案中更新;O)【参考方案2】:

您有两个选择: 1) 将一个信号编码到 MyServer 类中,该类将更新 gui 所需的数据和一个插槽编码到 MainWindow 类中,该类执行更新 ui 并将信号与插槽连接的工作。

或 2)您可以将指向 MainWindow 的指针传递给 MyServer(也许成为父级是有意义的)并使用该指针调用您在 MainWindow 中编码的公共功能,并使用您需要的数据更新 ui。

LE:两个问题: 1)我看到你在堆栈上创建了 MyServer 实例到 *on_startButton_clicked* 中,如果该对象被如此快地销毁,这可能是一个问题,所以你应该确保只要你需要它就保持活动状态,以便它可以完成它的工作。 2)这条线应该做什么: connect(server,SIGNAL(newConnection()),this,SLOT(newConnection())); 即使你有一个 newConnection 信号你为什么要连接它进入您连接的插槽以及第一次应该如何连接,执行插槽并建立连接,所以检查您在那里做了什么......

【讨论】:

我怎样才能让 button_clicked 事件/函数保持活动状态? 你没有让函数保持活跃——你通过在堆上分配它来保持 MyServer 实例的活跃——就像 Merlin069 在他的帖子中所做的那样,但是您很可能不需要在每次单击按钮时进行分配,因此您可以在构造函数中分配并仅在单击时使用对象(通过该指针调用 MyServer 类上所需的功能)

以上是关于来自另一个类的 Qt c++ GUI 调用的主要内容,如果未能解决你的问题,请参考以下文章

从 Qt 中的信号调用成员函数的问题

qt多个工程之间调用

等待来自另一个类的 JApplet 中的用户输入

在 QT Creator 中使用 C++ 调用 Python 脚本

Visual C++ 2010 / QT:为啥调用类的赋值运算符?

怎样在MATLAB GUI界面中调用另外一个GUI界面