QRemoteObjectNode::remoteObjectAdded signal does not fire - qt

While learning how to use QtRO tech preview module, I tried a simple 3 node network ( A registry node, a source object remoting node, and a client node).
registry node main.cpp:
#include <QCoreApplication>
#include <QRemoteObjectRegistryHost>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QRemoteObjectRegistryHost host(QUrl("tcp://127.0.0.1:5557"));
return a.exec();
}
source node main.cpp:
#include <QCoreApplication>
#include <QRemoteObjectHost>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTimer timer;
timer.start(10000);
QRemoteObjectHost host;
if(!host.setHostUrl(QUrl("tcp://127.0.0.1:5556"))) qDebug() << "Host url " << host.lastError();
if(!host.setRegistryUrl(QUrl("tcp://127.0.0.1:5557"))) qDebug() << "Reg url " << host.lastError();
if(!host.enableRemoting(&timer, "HostTimer")) qDebug() << "Remoting error " << host.lastError();
return a.exec();
}
client node main.cpp:
#include <QCoreApplication>
#include <QRemoteObjectNode>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QRemoteObjectNode node(QUrl("tcp://127.0.0.1:5557"));
QObject::connect(&node, &QRemoteObjectNode::remoteObjectAdded,
[](const QRemoteObjectSourceLocation& info){
qDebug() << "New source added : " << info;
});
qDebug() << "Waiting for registry ";
node.waitForRegistry(10000);
qDebug() << "Already here sources : " << node.registry()->sourceLocations();
QTimer timer;
timer.start(5000);
QObject::connect(&timer, &QTimer::timeout,
[&](){
qDebug() << "New sources list : " << node.registry()->sourceLocations();
});
return a.exec();
}
I begin by starting the registry node, then the client node and finally the source node, with this launch sequence I expect to get the remoteObjectAdded fired up, but It didn't.
Your help will be highly appreciated.

I answer my question.
I used the wrong signal source in the connect method call.
the client node will be as :
#include <QCoreApplication>
#include <QRemoteObjectNode>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QRemoteObjectNode node(QUrl("tcp://127.0.0.1:5557"));
QObject::connect(node.registry(), &QRemoteObjectRegistry::remoteObjectAdded,
[](const QRemoteObjectSourceLocation& info){
qDebug() << "New source added : " << info;
});
qDebug() << "Waiting for registry ";
node.waitForRegistry(10000);
qDebug() << "Already here sources : " << node.registry()->sourceLocations();
QTimer timer;
timer.start(5000);
QObject::connect(&timer, &QTimer::timeout,
[&](){
qDebug() << "New sources list : " << node.registry()->sourceLocations();
});
return a.exec();
}
It is the registry who fire the signal not the node, It sound logic after all the source nodes are connected to the registry, so it fire the remoteObjectAdded signal.

Related

Qt console application quit is problematic, stack variables is not being destructed

When you close console application in Windows 10, in the following code, Boo object is not being destructed even it is a local variable. I tried to catch interrupts but it didnt worked. I tried to connect to aboutToQuit signal , it didn't worked as well. Is there any way to destruct an object just before quit?
class Boo {
public:
~Boo() {
std::cout << "i'm dying" << std::endl;
}
};
void handle_quit() {
std::cout << "I quit" << std::endl;
}
int main(int argc, char *argv[])
{
Boo test;
QCoreApplication app(argc, argv);
QTimer::singleShot(0, &app, [&]() {
std::cout << "hello world qt";
});
QObject::connect(&app, &QCoreApplication::aboutToQuit, [&]() {
handle_quit();
});
return app.exec();
}
Here is the answer:
If you close the concole application by closing cmd window, the application gets SIGBREAK interrupt. In that case, you need to destruct everthing in 5 seconds. After 5 second application is being terminated forcefully by the system. Since my stack is not being destructed in that case, I moved it to heap and destructed it as soon as I got SIGBREAK.
class Boo {
~Boo () {
//do destruction job..
}
}
std::shared_ptr<Boo> test;
void SigInt_Handler(int) {
//destruct in 5 second...
test.reset();
}
int main(int argc, char *argv[])
{
test = make_shared<Boo>();
signal(SIGBREAK , &SigInt_Handler);
QCoreApplication app(argc, argv);
QTimer::singleShot(0, &app, [&]() {
std::cout << "hello world qt";
});
return app.exec();
}

How to show every qDebug with new window?

I make a QT console program.
I want to show every command by new window.
How could I do that ??
main.cpp
I use system is win10 with QT.
#include <QCoreApplication>
#include <QDebug> //在文字視窗輸出文字功能函式
#include <QDir> //搜尋資料夾功能函式
#include <QFileInfo> //顯示檔案資訊
#include <QString> //字串函式
#include <QStringList> //字串陣列函式
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QDir mDir; //設定資料夾位置
qDebug() << mDir.exists(); //輸出確定是否有mDir資料夾
QString command = "frtomem -p WnaYooAQ ";
foreach(QFileInfo mitm, mDir.entryInfoList(Qfilter)) //列出所有資料夾中篩選的檔案內容
{
qDebug() << command << mitm.fileName();
}
return a.exec();
}
I just can show it by one console window.
can't separete it.

QVariant with custom class pointer does not return same address

I need to assign a pointer to a custom class in qml using QQmlContext::setContextProperty(). Another qml object has Q_PROPERTY of the same type to retrieve it again.
A simple test showed me that the conversion does not work like i thought.
#include <QCoreApplication>
#include <QDebug>
#include <QMetaType>
class TestClass
{
public: TestClass() { qDebug() << "TestClass()::TestClass()"; }
};
Q_DECLARE_METATYPE(TestClass*)
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "metaTypeId =" << qMetaTypeId<TestClass*>();
auto testObject = new TestClass;
QVariant variant(qMetaTypeId<TestClass*>(), testObject);
auto test = variant.value<TestClass*>();
qDebug() << testObject << variant << test;
return 0;
}
This tiny test application gives me an output like this:
metaTypeId = 1024
TestClass::TestClass()
0x1b801e0 QVariant(TestClass*, ) 0x0
I would really like to get the same pointer out again after converting it down to a QVariant. Later I will assign it to a qml context and then the conversation must work correctly.
This works for me using Qt 5.9:
#include <QVariant>
#include <QDebug>
class CustomClass
{
public:
CustomClass()
{
}
};
Q_DECLARE_METATYPE(CustomClass*)
class OtherClass
{
public:
OtherClass()
{
}
};
Q_DECLARE_METATYPE(OtherClass*)
int main()
{
CustomClass *c = new CustomClass;
OtherClass *o = new OtherClass;
QVariant v;
v.setValue(c);
QVariant v2;
v2.setValue(o);
qDebug() << v.userType() << qMetaTypeId<CustomClass*>() << v2.userType() << qMetaTypeId<OtherClass*>();
qDebug() << v.value<CustomClass*>() << c << v2.value<OtherClass*>() << o;
return 0;
}
And the output i got:
1024 1024 1025 1025
0x81fca50 0x81fca50 0x81fca60 0x81fca60
As #thuga mentioned in the comments, you need to use void* and static_cast along with QVariant::fromValue.
#include <QCoreApplication>
#include <QDebug>
#include <QMetaType>
class TestClass
{
public: TestClass() { qDebug() << "TestClass()::TestClass()"; }
};
Q_DECLARE_METATYPE(TestClass*)
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "metaTypeId =" << qMetaTypeId<TestClass*>();
auto testObject = new TestClass;
QVariant variant(QVariant::fromValue(static_cast<void*>(testObject)));
auto test = static_cast<TestClass*>(variant.value<void*>());
qDebug() << testObject << variant << test;
return 0;
}

Qt 4.8 Why my QIODevice not output a text in this code?

If used QTextStream console(stdout) - all work just fine, but if I wrote custom IODevice, after qInstallMsgHandler() no text in console
main.cpp
#include "remoteconsole.h"
#include <QCoreApplication>
#include <QDateTime>
#include <QTimer>
QTextStream *out;
void logOutput(QtMsgType type, const char *msg)
{
QString debugdate = QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss.zzz");
*out << debugdate << " " << type << msg << endl;
}
int main(int argc, char *argv[])
{
int i;
QCoreApplication a(argc, argv);
RemoteConsole * remote = new RemoteConsole(&a);
QTextStream console((QIODevice *)remote);
out = &console;
qDebug() << "start qInstallMsgHandler";
qInstallMsgHandler(logOutput);
qDebug() << "end qInstallMsgHandler"<<endl;
for(i=0;i<10;i++){
qDebug() << i<<endl;
}
QTimer *timer = new QTimer();
a.connect(timer, SIGNAL(timeout()), &a, SLOT(quit()));
timer->start(5000);
a.exec();
return 0;
}
my IODevice implementation in file remoteconsole.h .cpp
#ifndef REMOTECONSOLE_H
#define REMOTECONSOLE_H
#include <QIODevice>
#include <QDebug>
class RemoteConsole: public QIODevice
{
Q_OBJECT
public:
RemoteConsole(QObject *parent);
~RemoteConsole();
private:
Q_DISABLE_COPY(RemoteConsole)
protected:
qint64 readData(char* data, qint64 maxSize);
qint64 writeData(const char* data, qint64 maxSize);
};
#endif // REMOTECONSOLE_H
#include "remoteconsole.h"
RemoteConsole::RemoteConsole(QObject* parent=0) :
QIODevice(parent)
{
}
RemoteConsole::~RemoteConsole(){}
qint64 RemoteConsole::readData(char *data, qint64 maxlen){
qDebug() << data <<endl;
return maxlen;
}
qint64 RemoteConsole::writeData(const char *data, qint64 len){
printf("writeData");
qDebug() << data <<endl;
return len;
}
In future I want to expand this code with QTCPServer, that send debug outputs to client connected to the device by telnet or nc.
You don't get any text in console after qInstallMsgHandler call because you send all debug data into your RemoteConsole object.
Also you've got some other problems in your code.
You should call QIODevice::open before you can operate on that device.
In the RemoteConsole::writeData function you will have an infinite loop because you use qDebug() there. qDebug() will call logOutput which will call RemoteConsole::writeData again.

Why nothing is display when I use QWebpage

it's very stupid question but I don't understand why nothing is display in my qt console application when I use QWebpage :
This is my basic code :
#include <QCoreApplication>
#include <QtWebKitWidgets>
#include <QDebug>
#include <stdio.h>
#include <iostream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
/*QWebPage page;
page.settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
page.settings()->setAttribute(QWebSettings::AutoLoadImages, true);
page.settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
page.settings()->setAttribute(QWebSettings::PrintElementBackgrounds, true);
page.settings()->setAttribute(QWebSettings::PluginsEnabled, true);
page.mainFrame()->load(QUrl("http://myflowerpower.parrot.com/#plantdb/3"));
qDebug () << "source html : \n";
qDebug() << page.currentFrame()->toHtml();
QString htmlResult = page.currentFrame()->toHtml();*/
printf("test");
std::cout << "test std::cout\n";
qDebug() << "Debug Message";
qWarning() << "Warning Message";
qCritical() << "Critical Error Message";
bool result = a.exec();
return result;
}
If I uncomment the code, nothing is display, but if I comment QWebpage stuff it's work without problem. Have any idea ?
QCoreApplication can't handle GUI elements.
You need to use QApplication instead to support the GUI and the event framework.
And make sure that you have what is needed in your .pro file.
QT += widgets webkitwidgets
Hope that helps.

Resources