Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt signal to specific object's slot

I would like to know which of the following is the proper way of doing thing with signal/slot in Qt.

I need a way to have multiple instance of a Dialog, i.e: A and B. And I need to tell A to print "A" and B to print "B" from a different thread. So I believe I need something like either:

OPTION 1) A->print("A") and B->print("B")

or is it better to do:

OPTION 2) emit print("A") and emit print("B") and use a way that I don't know so only A catch the "A" and only B catch the "B".

I got the option 1 working like this:

class myClass : public QMainWindow
{
    Q_OBJECT

public:
    myClass (QWidget *parent = 0, Qt::WFlags flags = 0);
    ~myClass ();
    void doPrint(char* text)
    {
         emit mySignal(text);
    }
private:
    Ui::myClass ui;

public slots:
    void newLog(char* msg);

signals:
     void mySignal(char* msg);
};

myClass::myClass(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags)
{
    ui.setupUi(this);
    connect(this, SIGNAL(mySignal(char*)), this, SLOT(newLog(char*)));
}

void myClass::newLog(char* msg)
{
    ui.textEdit->append(msg);
}

and then all I have to do is:

myClass* instanceA = new myClass();
myClass* instanceB = new myClass();
instanceA->doPrint("A");
instanceB->doPrint("B");

is this right?

Thanks!


1 Answers

Since your slot is in another thread, you have to use the Meta-Object System to invoke the method asynchronously. The proper way to do this is to use QMetaObject::invokeMethod

DO NOT subclass QThread and override the run method. For details on this see: https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

void otherClass::printTo(myClass* instance, char* text)
{
    QMetaObject::invokeMethod(instance,        // pointer to a QObject
                              "doPrint",       // member name (no parameters here)
                              Qt::QueuedConnection,     // connection type
                              Q_ARG(char*, text));     // parameters
}

void myClass::doPrint(char* text)
{
    ui.textEdit->append(text);
}

myClass* instanceA = new myClass();
myClass* instanceB = new myClass();
printTo(instanceA, "A");
printTo(instanceB, "B");

If the char* type hasn't been registered with the Meta-Object System yet, do so with Q_DECLARE_METATYPE(char*);

then:

qRegisterMetaType<char*>("charPtr");
like image 194
pandacrunch1337 Avatar answered Oct 24 '25 18:10

pandacrunch1337



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!