سؤال

Qt الوثائق الدول التي الإشارات فتحات يمكن direct, queued و auto.

وذكرت أيضا أنه إذا كان الكائن الذي يملك فتحة 'حياة' في موضوع مختلف عن الكائن الذي يملك إشارة انبعاث هذه الإشارة سوف يكون مثل نشر الرسالة إشارة تنبعث منها سيعود على الفور و فتحة سيتم استدعاء الأسلوب في هدف الموضوع هو حلقة الحدث.

للأسف الوثائق لا تحدد ذلك 'حياة' تقف و لا أمثلة هو متاح.لقد حاولت التعليمة البرمجية التالية:

main.h:

class CThread1 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        msleep( 200 );
        std::cout << "thread 1 started" << std::endl;
        MySignal();
        exec();
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

main.cpp:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & oThread2, SLOT( MySlot() ) );
    oThread1.start();
    oThread2.start();
    oThread1.wait();
    oThread2.wait();
    return a.exec();
}

الناتج هو:

thread 2 started
thread 1 started

MySlot() هي لم تسمى :(.ما أفعله خطأ ؟

هل كانت مفيدة؟

المحلول

هناك عدد غير قليل من المشاكل مع الكود الخاص بك :

  • كما قلت من قبل إيفان على تنبعث منها الكلمة مفقود
  • جميع الكائنات الحية في الموضوع الرئيسي, فقط رمز في أساليب العيش في المواضيع الأخرى ، وهو ما يعني أن MySlot فتحة يمكن أن يسمى في الموضوع الرئيسي و أنا لست متأكدة من أن هذا ما تريد
  • فتحة الخاص بك لن يكون دعا منذ الحدث الرئيسي حلقة لن أطلقت :لديك اثنين من يدعو إلى الانتظار() فقط مهلة بعد وقت طويل جدا (وربما سوف تقتل التطبيق الخاص بك قبل أن يحدث ذلك) وأنا لا أعتقد أن هذا ما تريد إما على أية حال لديهم حقا أي استخدام في التعليمات البرمجية الخاصة بك.

هذا الرمز على الأرجح العمل (على الرغم من أنني لم تختبر) وأعتقد أنه يفعل ما تريد القيام به :

class MyObject : public QObject
{
    Q_OBJECT
public slots:
    void MySlot( void )
    {
        std::cout << "slot called" << std::endl;
    }
};

class CThread1 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 1 started" << std::endl;
        int i = 0;
        while(1)
        {
           msleep( 200 );
           i++;
           if(i==1000)
              emit MySignal();
        }
    }
signals:
    void MySignal( void );
};

class CThread2 : public QThread
{
    Q_OBJECT
public:
    void run( void )
    {
        std::cout << "thread 2 started" << std::endl;
        exec();
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CThread1 oThread1;
    CThread2 oThread2;
    MyObject myObject;
    QObject::connect( & oThread1, SIGNAL( MySignal() ),
        & myObject, SLOT( MySlot() ) );
    oThread2.start();
    myObject.moveToThread(&oThread2)
    oThread1.start();
    return a.exec();
}

الآن MyObject سوف يعيش في thread2 (بفضل moveToThread).

MySignal ينبغي أن ترسل من thread1 (الفكر لست متأكدا من ذلك ، قد يتم إرسالها من الترابط الرئيسي, لا يهم حقا).

لا حلقة الحدث هو مطلوب في thread1 منذ انبعاث إشارة لا تحتاج إلى حلقة الحدث.الحدث حلقة مطلوب في thread2 (lanched قبل exec()) تلقي إشارة.

MySlot سوف يطلق في thread2.

نصائح أخرى

لا فرعية QThread على Qt 4.4+

في حين Aiua الجواب هو جيد, أريد أن أشير إلى بعض القضايا مع QThread و Qt 4.6 او 4.7.

هذا المقال يلخص الامر: http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

عدم وجود وثائق على Qt جزء

للأسف المشكلة تنبع من عدم وجود تحديثات وثائق.قبل Qt 4.4 QThread لا الافتراضي تشغيل() التنفيذ ، مما يعني أن لديك إلى فئة فرعية QThread من أجل استخدامها.

إذا كنت تستخدم Qt 4.6 او 4.7 ثم كنت يكاد يكون من المؤكد أن لا فرعية QThread.

استخدام moveToThread

مفتاح الحصول على فتحات تنفيذ في عامل الموضوع هو استخدام moveToThread طريقة Aiua أشار.

يجب أن تنبعث منها إشارة إلى بداية الخيط الخاص بك وظيفة مثل

emit operateCut(examId,examName_examTemplate[examName].studentIdRec,examName_examTemplate[examName].choiceRecA,examName_examTemplate[examName].choiceRecB,examName_examTemplate[examName].objectRecA,examName_examTemplate[examName].objectRecB);

يمكنك إضافة أكثر من حجة واحدة في هذا إشارة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top