来自另一个类的 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 Creator 中使用 C++ 调用 Python 脚本