Qt发信号到特定对象的插槽

时间:2009-07-20 17:00:32

标签: qt dialog signals-slots

我想知道以下哪一项是在Qt中使用信号/插槽做事的正确方法。

我需要一种方法来拥有一个Dialog的多个实例,即:AB。我需要告诉A打印“A”和B来打印来自不同线程的“B”。所以我相信我需要这样的东西:

选项1) A->print("A")B->print("B")

或者做得更好:

选项2) emit print("A")emit print("B")并使用我不知道的方式,只有A抓住“A”并且只有{{} 1}}抓住“B”。

我得到了这样的选项1:

B

然后我要做的就是:

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);
}

这是对的吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

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

不要继承QThread并覆盖run方法。有关详细信息,请参阅:http://blog.qt.digia.com/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");

如果char *类型尚未在元对象系统中注册,请执行此操作 Q_DECLARE_METATYPE(char*);

然后:

qRegisterMetaType<char*>("charPtr");

答案 1 :(得分:1)

在这个简化的例子中,我认为你在选项1的正确路径上。但是,如果你不需要doPrint()方法,它会更好,这也可以消除对{的需要。 {1}}信号(至少在mySignal中)。相反,我会建议继承myClass中的线程,如果还没有,并做这样的事情:

QThread

然后你需要做这样的事情:

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);
};

显然,在大多数非示例代码中,您不会将字符串传递给run,而是生成在myClass* instanceA = new myClass(); myThread* threadA = new myThread(); connect(threadA, SIGNAL(mySignal(char*)), instanceA, SLOT(newLog(char*)), Qt::QueuedConnection); threadA->run( "A" ); 正在运行时运行的字符串。优点是,这可以使线程注意事项远离threadA,您只需要考虑它们所连接的位置。另一方面,您在线程中引入的依赖项较少,因为它们不需要知道myClass能够记录。