Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在QT中通过tcp套接字远程更改文本框数据?_Qt_Sockets_Qml - Fatal编程技术网

如何在QT中通过tcp套接字远程更改文本框数据?

如何在QT中通过tcp套接字远程更改文本框数据?,qt,sockets,qml,Qt,Sockets,Qml,我想用Qt-tcp-socket和QML一起编写一个程序。 我将把QML创建的textbox变量更改为远程客户端通过tcp套接字获取的新数据? 我的代码片段是: void Server::startRead() { client->waitForReadyRead(3000); QString buf= client->readAll(); qDebug() << buf; QQmlApplicationEngine engine; en

我想用Qt-tcp-socket和QML一起编写一个程序。 我将把QML创建的textbox变量更改为远程客户端通过tcp套接字获取的新数据? 我的代码片段是:

void Server::startRead()
{

   client->waitForReadyRead(3000);
   QString buf=  client->readAll();
   qDebug() << buf;
   QQmlApplicationEngine engine;
   engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

   QObject *rootObject = engine.rootObjects().first();
   QObject *qmlObject = rootObject->findChild<QObject*>("ttt");
   qDebug() << "before change"
   qDebug() << qmlObject->property("text");
   qmlObject->setProperty("text", "new data");
   qDebug() << "after change"
   qDebug() << qmlObject->property("text");

 }

我真的很感激

有很多方法可以做到这一点。下面的示例演示如何从cpp更改qml元素属性。如果您需要更改可见性,只需使用bool属性,而不是我在示例中使用的字符串

1。我认为这是一个很好的解决方案。

您可以创建qml适配器

class ServerQMLAdapter : public QQuickItem
{
    Q_OBJECT
Q_PROPERTY(QString data READ data WRITE setData NOTIFY dataChanged)
public:
  explicit ServerQMLAdapter(QQuickItem *parent = nullptr) : QQuickItem(parent){}
  QString data() const {
    return mData;
  }
  void setData(const QString &data) {
    if(mData == data)
      return;
    mData = data;
    emit dataChanged();
  }
private slots:
/**
this slots called on data read
*/
  void onDataRead(const QString &data) {
    setData(data);
  }
private:
  QString mData = QString();
};
在应用程序类中,您应该注册适配器

qmlRegisterType<ServerQMLAdapter>("ServerQMLAdapter", 1, 0, "ServerQMLAdapter");

2。您可以从cpp更改属性。

就像您在代码片段中所做的一样

auto rootObject = engine.rootObjects().first();
rootObject->setProperty("text", "new data");
并将此属性添加到qml文件中

import ServerQMLAdapter 1.0
Item {
  ServerQMLAdapter {
    id: myAdapter
  }
  Text {
    id: message
    text: myAdapter.data
  }
}
Item {
  id: rootItem
  property string text
  Text {
    id: message
    text: rootItem.text
  }
}
Item {
  id: rootItem
  function setText(data) {
    message.text = data;
  }
  Text {
    id: message
  }
}

3。使用调用的方法

从您的cpp文件

auto rootObject = engine.rootObjects().first();
QMetaObject::invokeMethod(rootObject, "setText",
                              Q_ARG(QVariant, QVariant::fromValue(data)));
并将函数添加到qml文件中

import ServerQMLAdapter 1.0
Item {
  ServerQMLAdapter {
    id: myAdapter
  }
  Text {
    id: message
    text: myAdapter.data
  }
}
Item {
  id: rootItem
  property string text
  Text {
    id: message
    text: rootItem.text
  }
}
Item {
  id: rootItem
  function setText(data) {
    message.text = data;
  }
  Text {
    id: message
  }
}

+1对于解决方案1-但在setter中,您应该在发出信号之前检查新值是否与旧值不同。@derM yee我应该修复它谢谢@Andrey Semenov我在我的问题中添加了qml文件。您能看一下吗?我的问题是,当客户端连接到我的服务器并将新数据发送到服务器中的文本框时,窗口应该出现,并将旧文本数据更改为新数据。但不幸的是,窗口会自动出现和消失。@rebwarkarimi将属性移到顶部项目。在你的情况下,这是一个窗口。向其添加id,并使用它,就像第二个示例中一样。不要试图从C++找到项目,这不是改变PROTICE的最好方法。亲爱的AndreySemenov,我可以找到项目,因为在用QDebug函数检查它并打印属性结果时,属性和Tabbox的值发生了变化,但是问题是窗口自动出现和消失。