How to get the same application instance handle from QT and WinApi - qt

My QT application uses WinApi library.
Now I have the following code:
//main.cpp
qDebug() << "main::instance = " << qApp; //0x29fe18
//lib.cpp
qDebug() << "library::instance = " << GetModuleHandle(NULL); // 0x400000
As you see, I'm getting different handles while my app has only one thread flow.
What's wrong?
Edit:
Yes, I guessed that those are kind of different things.
Question is: how do I get thread handle from both places (if code running from the same thread - I should get the same handle value, if there's 2 threads - I should get 2 different thread handles)?

We don't know what qApp is. Presumably it's a pointer to the global instance of QApplication. That's a C++ object instance in your process.
On the other hand GetModuleHandle(NULL) is the base address of your executable module.
These two things are completely different. You should not expect them to be the same.
According to your edit you aren't interested in either of these things and actually want to identify threads. For Win32 code you use GetCurrentThreadId. For Qt use QThread::currentThreadId().

Related

AttributeRead never sent by QOpcUaNode, unable to read node but able to write

I am writing a program in Qt and I use the QOpcUaNode class. To this point, I only had to write on the OPC using writeAttribute, and it worked fine (meaning my nodes are set up correctly as far as I can see).
Now, I also need to read the info stored in the nodes, and I can't get it to work, always receiving a QVariant(Invalid) when I try to display the attribute using qDebug()
From what I read in the documentation, the signal attributeRead must be emitted before I can read a node. I tried two different things to get this signal emitted:
readAttributes(QOpcUa::NodeAttribute::Value)
and
readValueAttribute()
Here is my code, Flow being my QOpcUaNode* and m_custom being a bool member of my class and initially set to false:
connect(Flow, &QOpcUaNode::attributeRead, this, &OPC_Client::custom);
qDebug() << Flow->readValueAttribute();
qDebug() << Flow->readAttributes(QOpcUa::NodeAttribute::Value);
int i(0);
while (m_custom != true) {qDebug() << i; i++;}
custom is a slot simply doing m_custom = true;
When I compile and start the program, once those lines are reached, the value of i goes up and never stops which means I suppose that the signal is never emitted. I first tried without the while loop, just reading the value without waiting and received a QVariant(Invalid)...
I write using Flow ->writeAttribute(QOpcUa::NodeAttribute::Value, true ,QOpcUa::Types::Boolean); and everything works fine.
Can someone help me with this please?

When Qt-5 will fail the connect

Reading Qt signal & slots documentation, it seems that the only reason for a new style connection to fail is:
"If there is already a duplicate (exact same signal to the exact same slot on the same objects), the connection will fail and connect will return false"
Which means that connection was already successful the first time and does not allow multi-connections when using Qt::UniqueConnection.
Does this means that Qt-5 style connection will always success? Are there any other reasons for failure?
The new-style connect can still fail at runtime for a variety of reasons:
Either sender or receiver is a null pointer. Obviously this requires a check that can only happen at runtime.
The PMF you specified for a signal is not actually a signal. Lacking proper C++ reflection capabilities, all you can do at compile time is checking that the signal is a non-static member function of the sender's class.
However, that's not enough to make it a signal: it also needs to be in a signals: section in your class definition. When moc sees your class definition, it will generate some metadata containing the information that that function is indeed a signal. So, at runtime, the pointer passed to connect is looked up in a table, and connect itself will fail if the pointer is not found (because you did not pass a signal).
The check on the previous point actually requires a comparison between pointers to member functions. It's a particularly tricky one, because it will typically involve different TUs:
one is the TU containing moc-generated data (typically a moc_class.cpp file). In this TU there's the aforementioned table containing, amongst other things, pointers to the signals (which are just ordinary member functions).
is the TU where you actually invoke connect(sender, &Sender::signal, ...), which generates the pointer that gets looked up in the table.
Now, the two TUs may be in the same application, or perhaps one is in a library and the other in your application, or maybe in two libraries, etc; your platform's ABI starts to get into play.
In theory, the pointers stored when doing 1. are identical to the pointers generated when doing 2.; in practice, we've found cases where this does not happen (cf. this bug report that I reported some time ago, where older versions of GNU ld on ARM generated code that failed the comparison).
For Qt this meant disabling certain optimizations and/or passing some extra flags to the places where we know this to happen and break user software. For instance, as of Qt 5.9, there is no support for -Bsymbolic* flags on GCC on anything but x86 and x86-64.
Of course, this does not mean we've found and fixed all the possible places. New compilers and more aggressive optimizations might trigger this bug again in the future, making connect return false, even when everything is supposed to work.
Yes it can fail if either sender or receiver are not valid objects (nullptr for example)
Example
QObject* obj1 = new QObject();
QObject* obj2 = new QObject();
// Will succeed
connect(obj1, &QObject::destroyed, obj2, &QObject::deleteLater);
delete obj1;
obj1 = nullptr;
// Will fail even if it compiles
connect(obj1, &QObject::destroyed, obj2, &QObject::deleteLater);
Do not try to register pointer type. I've used the macro
#define QT_REG_TYPE(T) qRegisterMetaType<T>(#T)
with pointer type CMyWidget*, that was the problem. Using the type directly worked.
No it's not always successful. The docs give an example here where connect would return false because the signal should not contain variable names.
// WRONG
QObject::connect(scrollBar, SIGNAL(valueChanged(int value)),
label, SLOT(setNum(int value)));

Is it possible in Qt to run an external process inside a subwindow of the main process?

I have a multi document program (call it HostProgram) . I would wish to have a process (call it GuestProcess) managing each open documents inside HostProgram in order to improve stability (if one of the Guest Process crashes I'm not forced to close the HostProgram and the other running GuestProccesses).
Is it possible using Qt library to render the GUI composing GuestProcess inside a SubWindow of HostProcess? If yes how?
Thanks in advance a lot for any help/hints you will be able to provide me.
If i right undestand your problem, then you can help:
bool QProcess::startDetached ( const QString & program, const QStringList & arguments) [static]
Starts the program program with the given arguments in a new process, and detaches from it. Returns true on success; otherwise returns false. If the calling process exits, the detached process will continue to live.
For example:
QProcess process;
process.setProcessChannelMode(QProcess::ForwardedChannels);
process.startDetached(/*you new task*/);

What are some best practices for debugging Qt signals and slots?

Debugging signals and slots can be hard, because the debugger does not jump to the slots of a signal when it is emitted. What are some best practices for debugging Qt signals and slots?
In particular
How do I make sure connections are set up successfully?
When should I use signals and slots, when should I avoid them?
What are the most efficient debugging techniques from your experience?
There was a blog post written a while back called 20 ways to debug Qt signals and slots
It addresses I think #1 and #3 of your questions.
For #2, I don't think there is really a hard and fast reason to use or not use signals/slots, as they are a pretty core concept of the GUI framework. Signals are a perfect way to decouple the knowledge of one component to another, allowing you to design reusable widgets that simply declare state changes or notifications. It is also a very good way to communicate GUI changes from non-GUI thread loops, by emitting a signal that the main thread can see.
There might be times where what you really want instead of a signal/slot is to use events, such as when a parent widget should become the event filter for a number of child widgets. The children still do not need to know about the parent, and the parent gets a more direct event as opposed to a signal connection.
On the same topic of events, there are times where what you really want is a bubbling up of an event from child -> parent -> grandparent -> etc. Signals would make less sense here because they are not meant as a way to determine whether the proposed event should result in an action (they could be used this way obviously). Events allow you to check the current state, decide whether this widget should do anything, or otherwise bubble them up the chain for someone else to inspect.
There is a really fantastic answer about The Difference Between Signals/Slots and Events. Here is a good snippet:
You "handle" events
You "get notified of" signal emissions
What I like about that quote is that it describes the different need case. If you need to handle an action in a widget, then you probable want an event. If you want to be notified of things happening, then you probably want a signal.
In addition to what have been said, here are additional tricks.
If you use QTest for your unit tests, then you can pass -vs argument to the executable and all signals will be shown in the console.
I looked at how QTest works, and it registers callbacks that is triggered when signal and slots are executed using QSignalDumper class. However, this API is not exported and might break any time. Here is how I was able to hook on all signals and slots on Linux with Qt 5.10 using GCC.
// QSignalSpyCallbackSet is defined in qt5/qtbase/src/corelib/kernel/qobject_p.h
struct QSignalSpyCallbackSet
{
typedef void (*BeginCallback)(QObject *caller, int signal_or_method_index, void **argv);
typedef void (*EndCallback)(QObject *caller, int signal_or_method_index);
BeginCallback signal_begin_callback,
slot_begin_callback;
EndCallback signal_end_callback,
slot_end_callback;
};
typedef void (*register_spy_callbacks)(const QSignalSpyCallbackSet &callback_set);
static void showObject(QObject *caller, int signal_index, const QString &msg)
{
const QMetaObject *metaObject = caller->metaObject();
QMetaMethod member = metaObject->method(signal_index);
qDebug() << msg << metaObject->className() << qPrintable(member.name());
}
static void onSignalBegin(QObject *caller, int signal_index, void **argv)
{
showObject(caller, signal_index, "onSignalBegin");
}
static void onSlotBegin(QObject *caller, int signal_index, void **argv)
{
showObject(caller, signal_index, "onSlotBegin");
}
int main(int argc, char *argv[])
{
static QSignalSpyCallbackSet set = { onSignalBegin, onSlotBegin, 0, 0 };
QLibrary qtcore("libQt5Core");
register_spy_callbacks reg = (register_spy_callbacks)qtcore.resolve("_Z32qt_register_signal_spy_callbacksRK21QSignalSpyCallbackSet");
if (reg) {
reg(set);
}
...
}
I believe that Qt should expose that API, because we could use it for so many things beyond debugging, such as monitoring the time spent in a slot, get statistics, etc.
How do I make sure connections are set up successfully?
You will see warnings in the console output from your application for each failed connection.
When should I use signals and slots, when should I avoid them?
In my opinion, it's fine to use them any time you want to maintain separation of concerns in your class design. Your class can emit a signal that may or may not be answered by another class (or classes) completely unknown to your class. This keeps your coupling down.
What are the most efficient debugging techniques from your experience?
I can't really add anything more than what is said on this blog post. 20 ways to debug Qt signals and slots
Regarding #1, I'll just add another piece of information that I didn't see mentioned above or in the referenced blog post.
From the documentation on QObject::connect():
Creates a connection of the given type from the signal in the sender object to the method in the receiver object. Returns true if the connection succeeds; otherwise returns false.
I prefer asserting the return value of my connection to make sure the connection succeeded, especially because not all Qt programs will have console output. This also leads to more easily maintainable code, as it will catch changes made at a later date to either the signal or the slot, and force the programmer who made the changes to update the connections as well.

Can anyone give me same someting to keep in mind while using signals and slots in Qt?

I am learning to program using Qt framework. When I writes some code have signals and slots involved, the events didn't seem to fire and the signals and slots didn't seem to work. It really me make me annoyed. Can you give me some cautions and warnnings about signals and slots in Qt?
slot declarations:
private slots:
void onFtpCmdFinish(int cmdId, bool error);
void onRealtimeFtpCmdsDone(bool error);
connection code:
ftpHandle = new QFtp( this );
connect(ftpHandle, SIGNAL(commandFinished(int, bool)), this, SLOT(onFtpCmdFinish(int, bool)));
connect(ftpHandle, SIGNAL(done(bool)), this, SLOT(onRealtimeFtpCmdsDone(bool)));
Thank you in advance!
In the future, if you ever happen to run into problems with your Qt signals and slots again, the contents of the following blog entry can turn out to be a real life-saver (or at least a very good starting point for your investigations):
http://samdutton.wordpress.com/2008/10/03/debugging-signals-and-slots-in-qt/
It meticulously lists 20 ways to debug/troubleshoot your signals and slots; follow this list and chances are high that you will eventually find out what's wrong.
I hope that helps.
You can only detect failed connect() at runtime.
A couple of tips:
defining QT-FATAL-WARNINGS=1 will cause Qt to assert and quit whenever it gets a connect that doesn't match.
Or wrapping each connect in:
bool ok = connect(……); QASSERT( ok);
Always check the return type, if its true then CONNECT successful else some thing wrong..
Don't forget about the fifth argument Qt::ConnectionType if you will write multithreaded applications

Resources