我想知道以下哪一项是在Qt中使用信号/插槽做事的正确方法。
我需要一种方法来拥有一个Dialog的多个实例,即:A
和B
。我需要告诉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);
}
这是对的吗?
谢谢!
答案 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
能够记录。