特定对象的Qt信号';s槽

特定对象的Qt信号';s槽,qt,dialog,signals-slots,Qt,Dialog,Signals Slots,我想知道以下哪项是处理Qt中信号/插槽的正确方法 我需要一种拥有多个对话框实例的方法,即:a和B。我需要告诉A打印“A”,告诉B从不同的线程打印“B”。所以我相信我需要这样的东西: 选项1)A->print(“A”)和B->print(“B”) 还是最好是: 选项2)emit print(“A”)和emit print(“B”)并使用一种我不知道的方法,因此只A捕捉“A”,只B捕捉“B” 我的选项1是这样工作的: class myClass : public QMainWindow {

我想知道以下哪项是处理Qt中信号/插槽的正确方法

我需要一种拥有多个对话框实例的方法,即:
a
B
。我需要告诉
A
打印“A”,告诉
B
从不同的线程打印“B”。所以我相信我需要这样的东西:

选项1)
A->print(“A”)
B->print(“B”)

还是最好是:

选项2)
emit print(“A”)
emit print(“B”)
并使用一种我不知道的方法,因此只
A
捕捉“A”,只
B
捕捉“B”

我的选项1是这样工作的:

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);
}
class myThread : public QThread
{
    Q_OBJECT

public:
    myThread (QWidget *parent = 0 ) : QThread(parent) {}
    ~myThread () {}
    void run(char* text)
    {
         emit mySignal(text);
    }

signals:
     void mySignal(char* msg);
};
myClass* instanceA = new myClass();
myThread* threadA = new myThread();
connect(threadA, SIGNAL(mySignal(char*)), instanceA, SLOT(newLog(char*)), Qt::QueuedConnection);
threadA->run( "A" );
然后我要做的就是:

myClass* instanceA = new myClass();
myClass* instanceB = new myClass();
instanceA->doPrint("A");
instanceB->doPrint("B");
是这样吗


谢谢

在这个简化的示例中,我认为您使用选项1的路径是正确的。但是,如果您不需要
doPrint()
方法就更好了,这样也就不需要
mySignal
信号(至少在
myClass
中)。相反,我建议您从
QThread
继承线程(如果尚未继承),并执行以下操作:

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);
}
class myThread : public QThread
{
    Q_OBJECT

public:
    myThread (QWidget *parent = 0 ) : QThread(parent) {}
    ~myThread () {}
    void run(char* text)
    {
         emit mySignal(text);
    }

signals:
     void mySignal(char* msg);
};
myClass* instanceA = new myClass();
myThread* threadA = new myThread();
connect(threadA, SIGNAL(mySignal(char*)), instanceA, SLOT(newLog(char*)), Qt::QueuedConnection);
threadA->run( "A" );
然后,您需要执行以下操作:

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);
}
class myThread : public QThread
{
    Q_OBJECT

public:
    myThread (QWidget *parent = 0 ) : QThread(parent) {}
    ~myThread () {}
    void run(char* text)
    {
         emit mySignal(text);
    }

signals:
     void mySignal(char* msg);
};
myClass* instanceA = new myClass();
myThread* threadA = new myThread();
connect(threadA, SIGNAL(mySignal(char*)), instanceA, SLOT(newLog(char*)), Qt::QueuedConnection);
threadA->run( "A" );

显然,在大多数非示例代码中,您不会将字符串传递到run,而是生成要在
threadA
运行时运行的字符串。这样做的好处是,它不需要考虑线程问题,而只需要考虑它们在哪里连接。另一方面,由于线程不需要知道
myClass
就可以登录,因此在线程中引入的依赖项较少。

由于插槽位于另一个线程中,因此必须使用元对象系统异步调用该方法。正确的方法是使用

不要将QThread子类化并重写run方法。有关详细信息,请参阅:

如果char*类型尚未向元对象系统注册,请使用
Q_DECLARE_元类型(char*)

然后:

qRegisterMetaType(“charPtr”);

请停止传播关于本例中需要Qt::QueuedConnection的错误信息。对于最后三个Qt版本,情况不再如此。@mmutz,在我的示例中,我这样做是为了确保连接的类型,基于“QThread对象位于创建对象的线程中,而不是在调用QThread::run()时创建的线程中。在QThread子类中提供插槽通常是不安全的。”然而,我现在看到了“您可以安全地从您的QThread::run()实现发出信号…”,这是我以前错过的。无论如何,指定连接类型不会损害我所看到的任何东西。让我们从问题的另一面开始。在这种情况下,您可能会对选项2感到满意?如果您只想打印“A”和“B”,可以举一个例子,说明第二种情况有优势吗?