QtQuick:如何使用 qml 中的 GUI 连接 tcp 客户端(信号/插槽)
我目前正在用QML代码中的GUI编写我的第一个Qtquick应用程序,其中包括TCP服务器。整个过程已经运行得很好,几个客户可以从定义的端口上的外部连接到服务器。 对于服务器代码,我主要保留以下来源:
https://www.bogotobogo.com/qt/qt5_asynchronous_qtcpserver_qthreadpool.php
< a href =“ ” ,一旦客户端从外部连接,类型客户端会动态创建一个新对象,并打开一个新的套接字。
void MyServer::incomingConnection(qintptr socketDescriptor)
{
// At the incoming connection, make a client
// and set the socket
MyClient *client = new MyClient(this);
client->setSocket(socketDescriptor);
}
我现在很难将myclient的对象连接到我的GUI(全部 *.QML)。然后,myclient类负责处理传入数据。 特别是在我的情况下,我在myclient :: readread()方法中解析了传入字节,并希望在GUI上触发相应的操作 /显示。 说我会在功能中有一些emit()调用。 如何直接将这些发射信号连接到GUI?
还是我总是必须先向MyServer类发送信号,然后它只能将信号传递给GUI? 那会很麻烦。 我希望直接将适当的信号从myclient类发送到GUI。
我有点被困在这里...
到目前为止,我只在Main.cpp中注册了MyServer课程到QML引擎。 这就是问题的症结所在。 QML引擎当前对MyServer类中的动态创建的对象/客户端(类型Myclient的)一无所知。
我的主要.cpp看起来像:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/main.qml"_qs);
// add global c++ object to the QML context as a property
MyServer myServer;
QQmlContext* context = engine.rootContext();
context->setContextProperty("myServer", &myServer); // the object will be available in QML with name "myServer"
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
// Create an instance of a server and then start it.
myServer.StartServer();
engine.load(url);
return app.exec();
}
如何解决这个问题? 优雅的解决方案会是什么样?
然后,我的“解决方法”实际上是在MyServer上提供许多插槽,以从客户端和插槽方法中发送每个信号,以将信号发送到GUI。正如我所说,超级笨拙且容易出错。
I'm currently writing my first QtQuick application with GUI in qml code that includes a TCP server. The whole thing is already running quite well and several clients can connect to the server from outside on the defined port.
For the server code, I mainly kept the following source:
https://www.bogotobogo.com/Qt/Qt5_Asynchronous_QTcpServer_QThreadPool.php
In other words, as soon as a client connects from the outside, a new object is created dynamically by the type client and a new socket is opened.
void MyServer::incomingConnection(qintptr socketDescriptor)
{
// At the incoming connection, make a client
// and set the socket
MyClient *client = new MyClient(this);
client->setSocket(socketDescriptor);
}
I am now having trouble connecting a object of type MyClient to my GUI (all in *.qml). The MyClient class is then responsible for processing incoming data.
In my case, in particular, I parse the incoming bytes in the MyClient::readyRead() method and want to trigger the corresponding action / display on the GUI.
Say I would have some emit() calls in the function.
How do I connect these emitting signals to the GUI in a straight way?
Or do I always have to send a signal to the MyServer class first and then it can only pass the signal on to the GUI?
That would be very cumbersome.
I would prefer to directly send the appropriate signals from the MyClient class to the GUI.
I'm kind of stuck here...
So far I have only registered the myServer class in my main.cpp to the Qml Engine.
That's the crux of the matter now.
The QML engine doesn't currently know anything about the dynamically created objects/clients (of type MyClient) inside the myserver class.
My main.cpp looks like:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/main.qml"_qs);
// add global c++ object to the QML context as a property
MyServer myServer;
QQmlContext* context = engine.rootContext();
context->setContextProperty("myServer", &myServer); // the object will be available in QML with name "myServer"
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
// Create an instance of a server and then start it.
myServer.StartServer();
engine.load(url);
return app.exec();
}
How to deal with this problem?
What would an elegant solution look like?
My "workaround" would then actually be to provide many slots on myServer for each signal to be sent from the client and within the slot method to send a signal to the GUI. As I said, super cumbersome and error-prone.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有很多方法可以做到。假设您的信号类似于
MyClient::dataWasRead()
。您可以将其连接到 MyServer(因为 MyServer 知道所有不同的客户端),然后 MyServer 可以发出自己的信号MyServer::dataWasRead(int clientIndex)
。 GUI 可以侦听该信号并知道该信号来自哪个客户端。您甚至可以在 MyServer 中提供访问器函数,以便 GUI 可以在需要时直接访问客户端。 (类似于MyServer::getClient(clientIndex)
。)取决于您的应用程序的需求。There's lots of ways it could be done. Let's say your signal is something like
MyClient::dataWasRead()
. You could connect that to MyServer (since MyServer knows about all the different clients), and then MyServer could emit its own signalMyServer::dataWasRead(int clientIndex)
. The GUI could listen for that signal and know which client the signal came from. You could even provide an accessor function in MyServer so the GUI could directly access the clients if needed. (Something likeMyServer::getClient(clientIndex)
.) Depends on the needs of your app.