QState::assignProperty doesn't work - c++

I'm trying to add to qstatemachine a property with string and an enum, but the result from the machine.property() is empty.
QStatemachine m_machine;
idle->assignProperty(&m_machine, "state", Z_IDLE);
cool->assignProperty(&m_machine, "state", Z_COOL);
start_z->assignProperty(&m_machine, "state", Z_START);
QVariant st = m_machine->property("state");
QString s = st.toString();
I tried to show my approach to see if that can work or no.
Update:
idle = new QState();
start_z = new QState();
lock = new QState();
connect(this, SIGNAL(machine_exec()), this, SLOT(idle_exec()));
connect(this, SIGNAL(machine_exec()), this, SLOT(start_z_exec()));
connect(this, SIGNAL(machine_exec()), this, SLOT(sample_exec()));
m_machine->addState(idle);
m_machine->addState(start_z);
m_machine->addState(lock);
idle->assignProperty(m_machine, "state", Z_IDLE);
cool->assignProperty(m_machine, "state", Z_COOL);
start_z->assignProperty(m_machine, "state", Z_START);
idle->addTransition(this, SIGNAL(machineToStart()), start_z);
cool->addTransition(this, SIGNAL(machineToMotDn()), motDn);
motDn->addTransition(this, SIGNAL(machineToFini()), fini);
void MeasController::idle_exec()
{
qDebug()<<"idle_exec";
emit machineToStart();
}
void MeasController::start_z_exec()
{
qDebug()<<"start_z_exec";
QVariant s = m_machine->property("state");
qDebug()<<"property value"<<s.toString();
if (m_machine->property("state") == Z_START) {
emit machineStartToSample();
}
}

The properties are assigned on state transitions only, so if you check the value of the property before the machine was started and the event loop had a chance to run, you won't get a valid value.
Additionally, by using the name of the property multiple times, you're liable to commit a typo. Instead of string literals, you should be using named constants for property names - and they should be sufficiently different that random typos will get caught. I.e. property names like kStateA and kStateB are probably too similar - a typo would be silent.
So, I'd change the code to be:
static const char kState[] = "state";
QStatemachine m_machine;
idle->assignProperty(&m_machine, kState, Z_IDLE);
cool->assignProperty(&m_machine, kState, Z_COOL);
start_z->assignProperty(&m_machine, kState, Z_START);
qDebug() << m_machine->property(kState).toString();
Also note that this notion of a single current state only applies if your machine is non-hierarchical. A general HSM, as implemented by QStateMachine, is always in a set of states, available from configuration(). Most realistic machines should be hierarchical, so your approach won't work.
It is also unclear that there's any use for the _exec methods, as well as the explicit signals used to transition between states.
Below is a complete example of approaches that you might find useful.
First, let's start with how one might concisely specify your MeasController:
class MeasController : public QObject {
Q_OBJECT
QStateMachine m_machine{this};
NamedState
m_idle {"Idle", &m_machine},
m_start_z {"Start Z", &m_machine},
m_active_z{"Active Z", &m_machine},
m_downMove{"DownMove", &m_machine};
Transition
m_toStartZ{&m_idle, &m_start_z},
m_toDownMove{&m_active_z, &m_downMove};
Delay
m_d1{&m_start_z, &m_active_z, 1000},
m_d2{&m_downMove, &m_active_z, 2000};
QList<QState*> states() const { return m_machine.findChildren<QState*>(); }
public:
MeasController(QObject * parent = 0) : QObject(parent) {
for (auto state : states())
connect(state, &QState::entered, [state]{ qDebug() << state->objectName(); });
m_machine.setInitialState(&m_idle);
m_machine.start();
}
Q_SLOT void startZ() { m_toStartZ.trigger(); }
Q_SLOT void moveDown() { m_toDownMove.trigger(); }
};
This is a complete specification of the state machine. The states and their transitions and other behaviors are given as members of MeasController, and are thus easy to find in one place. For ease of debugging, debug output is provided upon each state being entered. Slots are provided to trigger behaviors from outside of the class without having to expose the internals.
Let's now look at the idioms defined by the NamedState, Transition and Delay classes.
A named state idiom, similar to Qt 3's QObject taking name in the constructor, is useful for debugging at the very least. If you want to assign any other properties of the state, you can do so in this class as well. Since the states have unique variable names and are members of the parent class any integer identifiers aren't necessary:
// https://github.com/KubaO/stackoverflown/tree/master/questions/state-properties-36745219
#include <QtWidgets>
class NamedState : public QState { Q_OBJECT
public:
NamedState(const char * name, QStateMachine * parent) : QState(parent) {
setObjectName(QString::fromUtf8(name));
}
};
A transition class is useful to give a concise way of specifying the structure of your state machine as simple member definitions of Transition instances:
struct Transition : public QObject { Q_OBJECT
public:
Transition(QState * source, QState * destination) : QObject(source->machine()) {
source->addTransition(this, &Transition::trigger, destination);
}
Q_SIGNAL void trigger();
};
I'm sure that your state machine has more complex behaviors, but generally it helps to factor out a certain behavior into its own class. E.g. say you want a state transition that occurs after a delay:
class Delay : public Transition { Q_OBJECT
int m_delay;
QBasicTimer m_timer;
void timerEvent(QTimerEvent * ev) {
if (m_timer.timerId() != ev->timerId()) return;
m_timer.stop();
trigger();
}
public:
Delay(QState * s, QState * d, int ms) : Transition(s, d), m_delay(ms) {
connect(s, &QState::entered, this, [this]{ m_timer.start(m_delay, this);});
}
};
Finally, we can offer a simple UI to test and visualize the behavior of the machine. The debug output is duplicated in a QPlainTextEdit for ease of use.
int main(int argc, char ** argv) {
QApplication app{argc, argv};
MeasController ctl;
QWidget w;
QGridLayout layout{&w};
QPushButton start{"Start"};
QPushButton moveDown{"Move Down"};
QPlainTextEdit log;
log.setReadOnly(true);
layout.addWidget(&start, 0, 0);
layout.addWidget(&moveDown, 0, 1);
layout.addWidget(&log, 1, 0, 1, 2);
QObject::connect(&start, &QPushButton::clicked, &ctl, &MeasController::startZ);
QObject::connect(&moveDown, &QPushButton::clicked, &ctl, &MeasController::moveDown);
static QtMessageHandler handler = qInstallMessageHandler(
+[](QtMsgType t, const QMessageLogContext& c, const QString & msg){
static QPointer<QPlainTextEdit> log{[]{
for (auto w : qApp->topLevelWidgets())
for (auto log : w->findChildren<QPlainTextEdit*>()) return log;
Q_ASSERT(false);
}()};
if (log) log->appendPlainText(msg);
handler(t, c, msg);
});
w.show();
return app.exec();
}
#include "main.moc"
This concludes the complete example. This is a longer example in a somewhat similar style.

Related

Accessing the QPushButton in the callback function

I want to enable a pushbutton in a callback function. I have tried to do the following but I have got:
Runtime received SIGSEGV (address: 0x28 reason: address not mapped to object)
class MyWindow: public QDialog
{
Q_OBJECT
public:
QPushButton *Btn;
void Scan();
....
};
extern void StartScan(pfcallback);
void MyWindow::Scan()
{
Btn->setEnabled(false);
StartScan(Scanfinished);
}
void static Scanfinished()
{
Btn->setEnabled(true);
}
How to access the button in the callback function Scanfinished() ?
You're attempting to manually manage memory. As you can see, it's very easy to use a dangling pointer or commit other blunders. Instead, let the compiler do it for you.
You use static incorrectly.
If I were to do it, I'd do as follows. The destructor is generated by the compiler and will correctly release all resources and reset m_instance to a null value.
class MyWindow : public QDialog
{
Q_OBJECT
static QPointer<MyWindow> m_instance;
QVBoxLayout m_layout{this};
QPushButton m_button{"Scan"};
public:
MyWindow(QWidget * parent = nullptr) : QDialog(parent) {
Q_ASSERT(! m_instance);
m_instance = this;
m_layout.addWidget(&m_button);
}
void Scan();
static void ScanFinished();
};
QPointer<MyWindow> MyWindow::m_instance;
void StartScan(void(*callback)());
void MyWindow::Scan()
{
m_button.setEnabled(false);
StartScan(ScanFinished);
}
void MyWindow::ScanFinished()
{
m_instance->m_button.setEnabled(true);
}
At this point it's rather obvious that the API of StartScan is horribly broken, and this brokenness forces the use of a singleton MyWindow. When doing any kind of callbacks, you never use a sole C function pointer. You must accept both a function pointer that takes a void* and a void* that will be used to carry the data the function needs to work. This is an idiom. If you use C-style callbacks, you cannot not use the idiom without severely crippling the usability of your API.
Thus, this is a complete example and works in both Qt 4 and Qt 5. You should have posted something like it - a self-contained test case - in your question. It compiles and it works and you can even get the complete Qt Creator project from github. It will compile and run on all platforms supported by current Qt. It's not supposed to be hard: that's why you're using Qt, after all. Getting in the habit of creating such concise test cases to demonstrate your issues will make you a better developer, and make your questions much easier to answer.
// https://github.com/KubaO/stackoverflown/tree/master/questions/simple-callback-43094825
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#include <QtConcurrent>
#endif
class MyWindow: public QDialog
{
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_button{"Scan"};
Q_SIGNAL void ScanFinished();
public:
MyWindow(QWidget * parent = nullptr) : QDialog(parent) {
m_layout.addWidget(&m_button);
connect(&m_button, SIGNAL(clicked(bool)), this, SLOT(Scan()));
connect(this, SIGNAL(ScanFinished()), this, SLOT(OnScanFinished()));
}
Q_SLOT void Scan();
static void ScanFinishedCallback(void* w);
Q_SLOT void OnScanFinished();
};
void StartScan(void(*callback)(void*), void* data) {
// Mockup of the scanning process: invoke the callback after a delay from
// a worker thread.
QtConcurrent::run([=]{
struct Helper : QThread { using QThread::sleep; };
Helper::sleep(2);
callback(data);
});
}
void MyWindow::Scan()
{
m_button.setEnabled(false);
StartScan(ScanFinishedCallback, static_cast<void*>(this));
}
void MyWindow::ScanFinishedCallback(void* data)
{
emit static_cast<MyWindow*>(data)->ScanFinished();
}
void MyWindow::OnScanFinished()
{
m_button.setEnabled(true);
}
int main(int argc, char ** argv) {
QApplication app(argc, argv);
MyWindow w;
w.show();
return app.exec();
}
#include "main.moc"
Of course StartScan cannot do the work in the thread it was called from: it'd block the GUI thread and make your application unresponsive. That's the prime source of bad user experience. Instead, it should spawn a concurrent job that will notify the caller when the scanning is done.
Since the callback will be called from that concurrent thread, it's not safe to use MyWindow's non-thread-safe methods. The only thread-safe methods are signals - thus we can emit a signal that Qt will the safely forward to MyWindow's thread and invoke OnScanFinished from the right thread.

RAII and Qt signals

I'm trying to understand and use RAII and wanted opinions on this implementation:
I want the RAII PauseProcessRAII to emit a signal and another one in the destructor. Example:
// Header
public:
PauseProcessRAII(QObject *parent = 0);
void Execute();
~PauseProcessRAII();
signals:
void PauseProcess(bool pause_process);
// Source
PauseProcessRAII::~PauseProcessRAII()
{
emit PauseProcess(false);
}
void PauseProcessRAII::Execute()
{
emit PauseProcess(true);
}
// MainWindow code
void MainWindow::OnPauseProcessRAII(bool pause_process)
{
qDebug() << "pause_process: " << pause_process;
}
void MainWindow::OnButtonSaveClicked()
{
PauseProcessRAII pauseProcessRAII(this);
connect(&pauseProcessRAII, &PauseProcessRAII::PauseProcess, this, &MainWindow::OnPauseProcess);
pauseProcessRAII.Execute();
// ... Some code runs
// ... pauseRAII desctructor is called
}
When I run the code both emits are firing as expected. My question is this a good solution? At first I though the emit call in PauseProcessRAII destructor wouldn't have worked because it may have destroyed the signal and slot connection. Of course that would mean I would have to add the connect to every function that I use it on.
The whole idea is fundamentally broken if your premise is that the code indicated by "Some code runs" runs long enough to block the GUI. If so: don't do that. The only code that is supposed to ever execute in the GUI thread is short, run-to-completion code that doesn't take long enough for the user to notice.
If the time taken by "Some code runs" is very short - on the order of single milliseconds at most - then you can certainly use such a construct. The term RAII doesn't apply here, as you're dealing with some sort of a scope guard.
If you wish, you can forgo the execute method and perform the connection in the constructor:
// https://github.com/KubaO/stackoverflown/tree/master/questions/scopeguard-signal-34910879
// main.cpp
#include <QtCore>
class ScopeSignaller : public QObject {
Q_OBJECT
public:
Q_SIGNAL void inScope(bool);
template <typename F>
ScopeSignaller(QObject * target, F && slot, QObject * parent = 0) : QObject(parent) {
connect(this, &ScopeSignaller::inScope, target, std::forward<F>(slot));
inScope(true);
}
~ScopeSignaller() {
inScope(false);
}
};
int main(int argc, char ** argv) {
QCoreApplication app{argc, argv};
ScopeSignaller s(&app, +[](bool b){ qDebug() << "signalled" << b; });
}
#include "main.moc"

How we can access #define variable from structure

I have defined macros for members that I want to access from a structure. I don't want to type cast to any another data type.
Example:
#define LABLE ui->lable->setText("NumbVal")
#define LABLE1 ui->lEditCaliCLFltBst->setText("UNDER PROCESS")
if (EditMode[LOC_04]!=0) { LABLE; } else { LABLE1; }
I want to access this LABLE variable from a structure. But what if I have a larger number of EditMode array entried - I can't make my program lenthy I just want to access through them through a structure.
What you are showing should be, at the very least, functions.
For example:
class Foo : public QWidget {
QScopedPointer<Ui::Foo> ui; // Don't use a raw pointer!
enum { LOC_04, LOC_END };
int m_editMode[LOC_END];
void lable1() { ui->lable->setText("NumbVal"); }
void lable2() { ui->lEditCaliCLFltBst->setText("UNDER PROCESS"); }
...
void f() {
...
if (EditMode[LOC_04]!=0) lable1(); else lable2();
...
}
}
With the little code you've shown, I infer that you have an interface that can be in various states, and those states are indicated through multiple user interface elements. This is what QStateMachine is for.
The example below demonstrates the following:
The use of a state machine to control the appearance of the user interface in each state.
The user interface has two parallel states: the m_editState and the m_boldState. The states are parallel, meaning that the state machine is in both of those states at the same time. Imagine this was in a text editor of some sort.
The edit state can be in one of two substates: m_edit1 and m_edit2. Similarly, the bold state can be in two states: m_boldOn and m_boldOff.
Clicking the buttons switches the states, and modifies the indications on the labels.
Concise setup of a user interface without using the UI designer.
Direct use of QObject members in a QObject, without explicit heap storage. Note the absence of a single explicit new and delete in the entire code. This shouldn't be an end unto itself, but it certainly helps avoid some pitfalls of unmanaged pointers, and it halves the number of heap allocations per each object. This pattens also works great when you put all the members in a pimpl class.
A reasonably concise way of repeating some code for elements of a constant list, created in place. This is pre-C++11 code.
Referring back to your original code, perhaps the EditMode could be represented by a set of states. If there are multiple aspects of the EditMode, they'd be represented by parallel states - perhaps each entry in EditMode would be a parallel state. Without knowing anything else about what you intend to achieve, it's hard to tell.
#include <QApplication>
#include <QLabel>
#include <QPushButton>
#include <QStateMachine>
#include <QGridLayout>
class Widget : public QWidget {
QGridLayout m_layout;
QLabel m_label1, m_label2, m_label3;
QPushButton m_button1, m_button2, m_button3;
QStateMachine m_machine;
QState m_editState, m_boldState, m_edit1, m_edit2, m_boldOn, m_boldOff;
public:
Widget(QWidget * parent = 0) : QWidget(parent), m_layout(this),
m_label1("--"), m_label2("--"), m_label3("--"),
m_button1("Edit State 1"), m_button2("Edit State 2"), m_button3("Toggle Bold State"),
m_editState(&m_machine), m_boldState(&m_machine),
m_edit1(&m_editState), m_edit2(&m_editState),
m_boldOn(&m_boldState), m_boldOff(&m_boldState)
{
m_layout.addWidget(&m_label1, 0, 0);
m_layout.addWidget(&m_label2, 0, 1);
m_layout.addWidget(&m_label3, 0, 2);
m_layout.addWidget(&m_button1, 1, 0);
m_layout.addWidget(&m_button2, 1, 1);
m_layout.addWidget(&m_button3, 1, 2);
m_edit1.assignProperty(&m_label1, "text", "Edit State 1");
m_edit2.assignProperty(&m_label2, "text", "Edit State 2");
m_boldOn.assignProperty(&m_label3, "text", "Bold On");
m_boldOff.assignProperty(&m_label3, "text", "Bold Off");
m_editState.setInitialState(&m_edit1);
m_boldState.setInitialState(&m_boldOff);
foreach (QState * s, QList<QState*>() << &m_edit1 << &m_edit2) {
s->addTransition(&m_button1, SIGNAL(clicked()), &m_edit1);
s->addTransition(&m_button2, SIGNAL(clicked()), &m_edit2);
}
m_boldOn.addTransition(&m_button3, SIGNAL(clicked()), &m_boldOff);
m_boldOff.addTransition(&m_button3, SIGNAL(clicked()), &m_boldOn);
m_machine.setGlobalRestorePolicy(QState::RestoreProperties);
m_machine.setChildMode(QState::ParallelStates);
m_machine.start();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

Signal/Slot with return value doesn't work

I made a signal slot in Qt and the program runs without error or warnings about the connect i made. The problem is that when i want to use the signal slot, it always returns NULL.
Main.cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Game* game = new Game;
Scrabble mainWindow;
mainWindow.show();
QObject::connect(&mainWindow,SIGNAL(getTurn()),game,SLOT(giveTurn()));
return a.exec();
}
Game.h
class Game: public QObject
{
Q_OBJECT
public:
Game(QObject *parent = 0);
~Game();
private:
int m_turn;
public slots:
int giveTurn();
};
Game.cpp
Game::Game(QObject *parent)
:QObject(parent)
{
m_turn = 1;
}
Game::~Game()
{
}
int Game::giveTurn()
{
return m_turn;
}
Scrabble.h
class Scrabble : public QMainWindow
{
Q_OBJECT
public:
explicit Scrabble(QWidget *parent = 0);
~Scrabble();
private:
Ui::Scrabble *ui;
signals:
int getTurn();
};
when i use int turn = emit getTurn(); in Scrabble.cpp, turn will become 0 and not 1.
Does anyone know what i'm doing wrong?
You're using signals and slots incorrectly. Signals cannot return value. See the Signals & Slots documentation page:
Signals are automatically generated by the moc and must not be implemented in the .cpp file. They can never have return types (i.e. use void).
Returning values from signals is not required when you use Qt features correctly. Maybe you should create another question and describe what you want to do and why you need such connection. You're definitely doing something wrong.
Signals/slots cant return any value. Possible solution:
Scrabble:
signal: void requestTurn();
public slot: receiveTurn(int);
Game:
public slot: onrequestTurn();
signal: sendTurn(int);
emit "keyword" is highly undocumented right now, but from Qt's source, it is only empty define, so your code
int turn = emit getTurn();
will be expanded to:
int turn = getTurn();
However, this is not covered in oficial documentation and it might change any time - so - don't use it!
Now, please note that turn variable is not getting value from slot, but from signal. There is nothing about passing return value from slot to signal - and it doesn't make sense (well, it may make sense in your sample, but what if I connect multiply slots to a single signal - what slot will return value, what if slots are executed asynchronously - should we wait for return value, etc.).
You can use regular function call (just call giveTurn() function: int turn = giveTurn()).

Can Qt signals return a value?

Boost.Signals allows various strategies of using the return values of slots to form the return value of the signal. E.g. adding them, forming a vector out of them, or returning the last one.
The common wisdom (expressed in the Qt documentation [EDIT: as well as some answers to this question ]) is that no such thing is possible with Qt signals.
However, when I run the moc on the following class definition:
class Object : public QObject {
Q_OBJECT
public:
explicit Object( QObject * parent=0 )
: QObject( parent ) {}
public Q_SLOTS:
void voidSlot();
int intSlot();
Q_SIGNALS:
void voidSignal();
int intSignal();
};
Not only doesn't moc complain about the signal with the non-void return type, it seems to actively implement it in such a way as to allow a return value to pass:
// SIGNAL 1
int Object::intSignal()
{
int _t0;
void *_a[] = { const_cast<void*>(reinterpret_cast<const void*>(&_t0)) };
QMetaObject::activate(this, &staticMetaObject, 1, _a);
return _t0;
}
So: according to the docs, this thing isn't possible. Then what is moc doing here?
Slots can have return values, so can we connect a slot with a return value to a signal with a return value now? May that be possible, after all? If so, is it useful?
EDIT: I'm not asking for workarounds, so please don't provide any.
EDIT: It obviously isn't useful in Qt::QueuedConnection mode (neither is the QPrintPreviewWidget API, though, and still it exists and is useful). But what about Qt::DirectConnection and Qt::BlockingQueuedConnection (or Qt::AutoConnection, when it resolves to Qt::DirectConnection).
OK. So, I did a little more investigating. Seems this is possible. I was able to emit a signal, and receive value from the slot the signal was connected to. But, the problem was that it only returned the last return value from the multiple connected slots:
Here's a simple class definition (main.cpp):
#include <QObject>
#include <QDebug>
class TestClass : public QObject
{
Q_OBJECT
public:
TestClass();
Q_SIGNALS:
QString testSignal();
public Q_SLOTS:
QString testSlot1() {
return QLatin1String("testSlot1");
}
QString testSlot2() {
return QLatin1String("testSlot2");
}
};
TestClass::TestClass() {
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot1()));
connect(this, SIGNAL(testSignal()), this, SLOT(testSlot2()));
QString a = emit testSignal();
qDebug() << a;
}
int main() {
TestClass a;
}
#include "main.moc"
When main runs, it constructs one of the test classes. The constructor wires up two slots to the testSignal signal, and then emits the signal. It captures the return value from the slot(s) invoked.
Unfortunately, you only get the last return value. If you evaluate the code above, you'll get: "testSlot2", the last return value from the connected slots of the signal.
Here's why. Qt Signals are a syntax sugared interface to the signaling pattern. Slots are the recipients of a signal. In a direct connected signal-slot relationship, you could think of it similar to (pseudo-code):
foreach slot in connectedSlotsForSignal(signal):
value = invoke slot with parameters from signal
return value
Obviously the moc does a little more to help in this process (rudimentary type checking, etc), but this helps paint the picture.
No, they can't.
Boost::signals are quite different from those in Qt. The former provide an advanced callback mechanism, whereas the latter implement the signaling idiom. In the context of multithreading, Qt's (cross-threaded) signals depend on message queues, so they are called asynchronously at some (unknown to the emitter's thread) point in time.
Qt's qt_metacall function returns an integer status code. Because of this, I believe this makes an actual return value impossible (unless you fudge around with the meta object system and moc files after precompilation).
You do, however, have normal function parameters at your disposal. It should be possible to modify your code in such a way to use "out" parameters that act as your "return".
void ClassObj::method(return_type * return_)
{
...
if(return_) *return_ = ...;
}
// somewhere else in the code...
return_type ret;
emit this->method(&ret);
You may get a return value from Qt signal with the following code:
My example shows how to use a Qt signal to read the text of a QLineEdit.
I'm just extending what #jordan has proposed:
It should be possible to modify your code in such a way to use "out" parameters that act as your "return".
#include <QtCore>
#include <QtGui>
class SignalsRet : public QObject
{
Q_OBJECT
public:
SignalsRet()
{
connect(this, SIGNAL(Get(QString*)), SLOT(GetCurrentThread(QString*)), Qt::DirectConnection);
connect(this, SIGNAL(GetFromAnotherThread(QString*)), SLOT(ReadObject(QString*)), Qt::BlockingQueuedConnection);
edit.setText("This is a test");
}
public slots:
QString call()
{
QString text;
emit Get(&text);
return text;
}
signals:
void Get(QString *value);
void GetFromAnotherThread(QString *value);
private slots:
void GetCurrentThread(QString *value)
{
QThread *thread = QThread::currentThread();
QThread *mainthread = this->thread();
if(thread == mainthread) //Signal called from the same thread that SignalsRet class was living
ReadObject(value);
else //Signal called from another thread
emit GetFromAnotherThread(value);
}
void ReadObject(QString *value)
{
QString text = edit.text();
*value = text;
}
private:
QLineEdit edit;
};
To use this, just request call();.
You can try to workaround this with following:
All your connected slots must save their results in some place (container) accessible from signaling object
The last connected slot should somehow (select max or last value) process collected values and expose the only one
The emitting object can try to access this result
Just as an idea.