2012-03-19 8 views
10

मेरे पास एक ऐसा एप्लिकेशन है जिसमें प्रत्येक थ्रेड (मुख्य धागे को छोड़कर) को अपनी खिड़की बनाने की आवश्यकता होती है। मैंने run फ़ंक्शन में 0 धागा बनाने और फिर this->exec() पर कॉल करने का प्रयास किया। हालांकि, मुझे उस कॉल तक पहुंचने से पहले एक त्रुटि मिलती है: ASSERT failure in QWidget: "Widgets must be created in the GUI thread."मैं अलग-अलग क्यूटी थ्रेड में विंडो कैसे बना सकता हूं?

मैं एक संदेश विंडो पॉप अप करना चाहता हूं। समस्या यह है कि स्रोत में कई धागे होते हैं जिनमें से प्रत्येक को अपना संदेश पॉप अप करने की आवश्यकता हो सकती है।

+2

पृष्ठभूमि/कार्यकर्ता धागे से यूआई दिखाने का प्रयास न करें। इसके बजाय मुख्य जीयूआई थ्रेड से यूआई दिखाएं। ऐसा करने के लिए जीयूआई थ्रेड को सिग्नल करने के लिए अपनी पृष्ठभूमि/कार्यकर्ता की व्यवस्था करें। यह उदाहरण दिखाता है कि यह कैसे करें: http://doc.qt.nokia.com/4.7-snapshot/thread-basics.html#example-3-clock। –

उत्तर

19

आप इस तरह के तरीके से लागू कर सकते हैं आप QWidget (या कुछ अन्य जीयूआई घटक (रों)) अलग (गैर मुख्य) में बनाने के लिए धागा (रों) की जरूरत है:

  • सरल आवरण बनाएं जो

    :

    // gui component holder which will be moved to main thread 
    class gui_launcher : public QObject 
    { 
        QWidget *w; 
        // other components 
        //.. 
    public: 
        virtual bool event(QEvent *ev) 
        { 
        if(ev->type() == QEvent::User) 
        { 
         w = new QWidget; 
         w->show(); 
         return true; 
        } 
        return false; 
        } 
    }; 
    
  • मुख्य थ्रेड

  • एक और धागा शरीर में QApplication वस्तु बनाने: जीयूआई घटक रखती है

    .. 
        // create holder 
        gui_launcher gl; 
        // move it to main thread 
        gl.moveToThread(QApplication::instance()->thread()); 
        // send it event which will be posted from main thread 
        QCoreApplication::postEvent(&gl, new QEvent(QEvent::User)); 
    .. 
    
  • निष्पादित किए जाने वाले मुख्य जीयूआई धागा करने के लिए किसी भी कार्रवाई हस्तांतरण करने के लिए, खुश हो :)

+2

हैलो मैं सिर्फ मनोरंजन के \t टेम्पलेट वर्ग gui_launcher के लिए कुछ छोटे सुधार किया: सार्वजनिक QObject { mygui * w; // अन्य घटकों सार्वजनिक: \t शून्य add2Gui() \t \t { \t \t इस-> moveToThread (QApplication :: उदाहरण() -> धागा()); \t \t क्यूकोर आवेदन :: postEvent (यह, नया QEvent (QEvent :: उपयोगकर्ता)); \t \t} आभासी bool घटना (QEvent * EV) { अगर (ev-> टाइप() == QEvent :: उपयोगकर्ता) { w = नए mygui; डब्ल्यू-> शो(); सच वापसी; } झूठी वापसी; } }; – jamk

1

मुझे विश्वास नहीं है कि यह संभव है। अन्य गैर-जीयूआई घटक अन्य धागे में चल सकते हैं और आमतौर पर सिग्नल/स्लॉट तंत्र के माध्यम से संवाद करेंगे।

7

क्यूटी आपको केवल जीयूआई थ्रेड में जीयूआई तत्व बनाने देगा - आपको अन्य धागे से प्रदर्शित करने की क्या ज़रूरत है? गैर-जीयूआई थ्रेड से डेटा के साथ प्रगति पट्टी को अपडेट करने के उदाहरण के लिए This answer जैसे कुछ देखें।

अद्यतन: फिर

class MyWorkerThread : public QThread 
{ 
    Q_OBJECT 
signals: 
    void sendMessage(QString msg); 
private: 
    void run() 
    { 
    /* do stuff */ 
    emit sendMessage(QString("This thread is doing stuff!")); 
    /* do more stuff */ 
    } 
}; 

संकेत-स्लॉट के माध्यम से अपने जीयूआई करने के लिए इसे कनेक्ट:

आप प्रत्येक विंडो के लिए एक संदेश दिखाना चाहते हैं, तो आप इस तरह एक वर्ग हो सकता है की तरह कुछ के साथ तंत्र:

connect(workerThread, SIGNAL(sendMessage(QString)), 
     guiController, SLOT(showMessageBox(QString))); 

कहाँ showMessageBox समारोह आप इसे क्या करने की जरूरत है।

+0

अद्यतन प्रश्न – chacham15

+0

एक छोटे से उदाहरण के साथ अद्यतन उत्तर :) – spbots

+0

प्रतीक्षा के लिए sry, मैं आपके जवाब का परीक्षण कर रहा था। – chacham15

0

ऊपर जवाब एक QAction वस्तु (या कस्टम वर्ग ऑब्जेक्ट) के साथ जोड़ा जा सकता है, बस नहीं विजेट बनाना या संदेश बॉक्स प्रदर्शित करना। (उदाहरण के लिए sendAction(QAction*) उत्सर्जित करके, QEvent कक्षा QAction* को जोड़कर एक कस्टम QEvent कक्षा को कार्यान्वित करके।)

संबंधित मुद्दे