• 9737阅读
  • 15回复

SIGNAL-SLOT  [dbzhang800请进] [复制链接]

上一主题 下一主题
离线butcherty
 

只看楼主 倒序阅读 楼主  发表于: 2010-05-21
在一个包括主次线程的程序中,主次线程之间通信可否直接用emit发送信号,在接收端直接connect另一线程发送的信号和本线程中的槽完成连接,如果可以connect(***, SIGNAL(), ***, SLOT())中的参数应该怎么来写?如果不能,那么怎么来实现,主线程需要给次线程发信号,次线程也要给主线程发信号。
[ 此帖被butcherty在2010-05-24 13:57重新编辑 ]
离线dbzhang800

只看该作者 1楼 发表于: 2010-05-21
可以,写法和没有线程时一样
离线butcherty

只看该作者 2楼 发表于: 2010-05-21
引用第1楼dbzhang800于2010-05-21 15:37发表的  :
可以,写法和没有线程时一样

但是不行阿,我前面有个帖子你还记得不? 运行提示  no such sigenal
离线dbzhang800

只看该作者 3楼 发表于: 2010-05-21
汗,那个帖子直到最后你都没用代码来证明你的“信号存在”
离线butcherty

只看该作者 4楼 发表于: 2010-05-21
引用第1楼dbzhang800于2010-05-21 15:37发表的  :
可以,写法和没有线程时一样

但是不行阿,我前面有个帖子你还记得不? 运行提示  no such sigenal
离线butcherty

只看该作者 5楼 发表于: 2010-05-21
引用第3楼dbzhang800于2010-05-21 16:02发表的  :
汗,那个帖子直到最后你都没用代码来证明你的“信号存在”


晕,我发了信号出去了阿,emit msgBoxsignal_0();  就是这样直接发的阿
离线dbzhang800

只看该作者 6楼 发表于: 2010-05-21
引用第5楼butcherty于2010-05-21 17:01发表的  :
晕,我发了信号出去了阿,emit msgBoxsignal_0();  就是这样直接发的阿


1. 贴你头文件 signals 部分
2. 贴你的包含connect语句的部分
3. 贴你的出错信息

不然 别人也不清楚 是你叙述出了问题,还是其他的问题
离线butcherty

只看该作者 7楼 发表于: 2010-05-21
引用第6楼dbzhang800于2010-05-21 17:17发表的  :
1. 贴你头文件 signals 部分
2. 贴你的包含connect语句的部分
3. 贴你的出错信息
.......


头文件部分
  signals:
    void msgBoxsignal_0();
    void msgBoxsignal_1();
    void msgBoxsignal_2();
    void msgBoxsignal_3();
    void msgBoxsignal_4();
    void msgBoxsignal_5();
    void msgBoxsignal_6();
    void msgBoxsignal_7();
    void msgBoxsignal_8();
    void msgBoxsignal_9();
    void msgBoxsignal_10();
    void msgBoxsignal_11();
    void msgBoxsignal_12();
    void msgBoxsignal_13();

connect  在主线程中
  b = new SerialThread(this);

  connect(b, SIGNAL(msgBoxsignal_0()), this, SLOT(msgBoxslot_0()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_1()), this, SLOT(msgBoxslot_1()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_2()), this, SLOT(msgBoxslot_2()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_3()), this, SLOT(msgBoxslot_3()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_4()), this, SLOT(msgBoxslot_4()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_5()), this, SLOT(msgBoxslot_5()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_6()), this, SLOT(msgBoxslot_6()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_7()), this, SLOT(msgBoxslot_7()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_8()), this, SLOT(msgBoxslot_8()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_9()), this, SLOT(msgBoxslot_9()), Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_10()), this, SLOT(msgBoxslot_10()),Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_11()), this, SLOT(msgBoxslot_11()),Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_12()), this, SLOT(msgBoxslot_12()),Qt::QueuedConnection);
  connect(b, SIGNAL(msgBoxsignal_13()), this, SLOT(msgBoxslot_13()),Qt::QueuedConnection);

编译正常,运行时候提示如下
Object::connect: No such signal QThread::msgBoxsignal_0()
Object::connect: No such signal QThread::msgBoxsignal_1()
Object::connect: No such signal QThread::msgBoxsignal_2()
Object::connect: No such signal QThread::msgBoxsignal_3()
Object::connect: No such signal QThread::msgBoxsignal_4()
Object::connect: No such signal QThread::msgBoxsignal_5()
Object::connect: No such signal QThread::msgBoxsignal_6()
Object::connect: No such signal QThread::msgBoxsignal_7()
Object::connect: No such signal QThread::msgBoxsignal_8()
Object::connect: No such signal QThread::msgBoxsignal_9()
Object::connect: No such signal QThread::msgBoxsignal_10()
Object::connect: No such signal QThread::msgBoxsignal_11()
Object::connect: No such signal QThread::msgBoxsignal_12()
Object::connect: No such signal QThread::msgBoxsignal_13()
[ 此帖被butcherty在2010-05-24 08:40重新编辑 ]
离线dbzhang800

只看该作者 8楼 发表于: 2010-05-21
引用第7楼butcherty于2010-05-21 18:00发表的  :
Object::connect: No such signal QThread::msgBoxsignal_0()
.......


这儿是 OThread 而不是你的 SerialThread,看来你需要贴出你的 SerialThread 的头文件了
离线butcherty

只看该作者 9楼 发表于: 2010-05-24
引用第8楼dbzhang800于2010-05-21 18:42发表的  :
这儿是 OThread 而不是你的 SerialThread,看来你需要贴出你的 SerialThread 的头文件了


public:
    SerialThread(MainWindow *parent);

  signals:
    void msgBoxsignal_0();
    void msgBoxsignal_1();
    void msgBoxsignal_2();
    void msgBoxsignal_3();
    void msgBoxsignal_4();
    void msgBoxsignal_5();
    void msgBoxsignal_6();
    void msgBoxsignal_7();
    void msgBoxsignal_8();
    void msgBoxsignal_9();
    void msgBoxsignal_10();
    void msgBoxsignal_11();
    void msgBoxsignal_12();
    void msgBoxsignal_13();

这是我的seriathread头文件中的声明
[ 此帖被butcherty在2010-05-24 08:46重新编辑 ]
离线xtfllbl

只看该作者 10楼 发表于: 2010-05-24
Signals and Slots Across Threads

Qt supports these signal-slot connection types:

Auto Connection (default) The behavior is the same as the Direct Connection, if the emitter and receiver are in the same thread. The behavior is the same as the Queued Connection, if the emitter and receiver are in different threads.
Direct Connection The slot is invoked immediately, when the signal is emitted. The slot is executed in the emitter's thread, which is not necessarily the receiver's thread.
Queued Connection The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
Blocking Queued Connection The slot is invoked as for the Queued Connection, except the current thread blocks until the slot returns. Note: Using this type to connect objects in the same thread will cause deadlock.
Unique Connection The behavior is the same as the Auto Connection, but the connection is made only if it does not duplicate an existing connection. i.e., if the same signal is already connected to the same slot for the same pair of objects, then the connection is not made and connect() returns false.
The connection type can be specified by passing an additional argument to connect(). Be aware that using direct connections when the sender and receiver live in different threads is unsafe if an event loop is running in the receiver's thread, for the same reason that calling any function on an object living in another thread is unsafe.

QObject::connect() itself is thread-safe.

The Mandelbrot example uses a queued connection to communicate between a worker thread and the main thread. To avoid freezing the main thread's event loop (and, as a consequence, the application's user interface), all the Mandelbrot fractal computation is done in a separate worker thread. The thread emits a signal when it is done rendering the fractal.

Similarly, the Blocking Fortune Client example uses a separate thread for communicating with a TCP server asynchronously.
上海欢迎您
离线xtfllbl

只看该作者 11楼 发表于: 2010-05-24
QT中的事件机制与信号-槽机制
1. 信号是较为高级的机制,事件是较为低级的机制。一般情况下,事件来自底层窗口系统,但是也有可能通过QApplication类的QApplication::sendEvent()和QApplication::postEvent()来手动发送事件。
2. 信号-槽中,信号触发多个槽是没有固定顺序的,会全部触发。(观察者模式)
事件触发的多个处理者是有固定的顺序的,优先级高的决定是否把事件继续传递下去(通过返回值)。(职责链模式)
3. 都可以用于跨线程环境,只不过信号-槽要采用“队列连接”或“自动连接(默认)”方式,不能采用“直接连接”(类似回调)。
4. QT手册第7章开头指出:使用信号-槽机制与事件机制的一个根本原则是,在使用一个组件时,使用信号;在实现一个组件时,使用事件机制。原因是:事件机制是更为底层的机制(也就是某些情况下没有相应信号可以接收),例如鼠标在组件上的划过,按下和抬起,在处理这类事件时,可以决定何时发出类似clicked()的信号。
5. QCoreApplication::postEvent(),可以给任何线程中的任何对象投递一个事件,事件会在那个创建了对象的线程中通过事件循环派发。事件过滤器在所有线程中也被支持,不过它限定被监视对象与监视对象生存在同一线程中。类似地, QCoreApplication::sendEvent(),仅用于在调用此函数的线程中向目标对象投递事件。
上海欢迎您
离线butcherty

只看该作者 12楼 发表于: 2010-05-24
引用第11楼xtfllbl于2010-05-24 14:12发表的  :
QT中的事件机制与信号-槽机制
1. 信号是较为高级的机制,事件是较为低级的机制。一般情况下,事件来自底层窗口系统,但是也有可能通过QApplication类的QApplication::sendEvent()和QApplication::postEvent()来手动发送事件。
2. 信号-槽中,信号触发多个槽是没有固定顺序的,会全部触发。(观察者模式)
事件触发的多个处理者是有固定的顺序的,优先级高的决定是否把事件继续传递下去(通过返回值)。(职责链模式)
3. 都可以用于跨线程环境,只不过信号-槽要采用“队列连接”或“自动连接(默认)”方式,不能采用“直接连接”(类似回调)。
.......


意思是上面这句的不能“直接连接”?能确定是在QT4中如此吗?这个reference应该是QT3的吧
[ 此帖被butcherty在2010-05-24 15:06重新编辑 ]
离线dbzhang800

只看该作者 13楼 发表于: 2010-05-24
Re:SIGNAL-SLOT  [dbzhang800请进]
算了,
给你一个简单的例子,
你可以做点修改,看看能不能给大家重现一下你提到的错误

main.cpp

#include <QtGui/QApplication>
#include <QtCore/QThread>
#include <QtGui/QMainWindow>
class MyThread:public QThread
{
    Q_OBJECT
public:
    MyThread(QObject * p=0):QThread(p)
    {
    }
signals:
    void msgSignal();
protected:
    void run()
    {
        emit msgSignal();
    }
};
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0):QMainWindow(parent)
    {
        m_thread = new MyThread(this);
        connect(m_thread, SIGNAL(msgSignal()), this, SLOT(onMsgSignal()));
        connect(m_thread, SIGNAL(msgNonExistSignal()), this, SLOT(onNonExistSignal()));
        m_thread->start();
    }
private slots:
    void onMsgSignal()
    {
        qDebug("signal received from MyThread!");
    }
private:
    MyThread * m_thread;
};
#include "main.moc"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}



test.pro
  1. TARGET = test
  2. SOURCES += main.cpp
  3. win32:CONFIG += console
离线butcherty

只看该作者 14楼 发表于: 2010-05-24
Re:Re:SIGNAL-SLOT  [dbzhang800请进]
引用第13楼dbzhang800于2010-05-24 15:32发表的 Re:SIGNAL-SLOT  [dbzhang800请进] :
算了,
给你一个简单的例子,
你可以做点修改,看看能不能给大家重现一下你提到的错误
main.cpp
.......


这个例子我看过的,我的程序感觉和这个没有太大差别,请指正,关键程序部分已全部发上
离线dbzhang800

只看该作者 15楼 发表于: 2010-05-24
Re:Re:Re:SIGNAL-SLOT  [dbzhang800请进]
引用第14楼butcherty于2010-05-24 17:22发表的 Re:Re:SIGNAL-SLOT  [dbzhang800请进] :
这个例子我看过的,我的程序感觉和这个没有太大差别,请指正,关键程序部分已全部发上


这样的话,只能建议你看“提问的智慧”了
快速回复
限100 字节
 
上一个 下一个