2009-12-28 18 views
5

नहीं कहा जाता है। मैं QMetaObject :: invokeMethod का उपयोग करके GUI थ्रेड पर एक विधि चलाने की कोशिश कर रहा हूं, जो सत्य लौटाता है। लेकिन, अगर मैं Qt :: QueuedConnection का उपयोग करता हूं तो मेरी विधि कभी भी कॉल नहीं होती है (भले ही invokeMethod सत्य लौटाए)।QMetaObject :: invokeMethod सत्य लौटाता है, लेकिन विधि को कभी भी

QMetaObject::invokeMethod(this, "draw_widgets", Qt::QueuedConnection) 

मैं अगर मैं क्यूटी :: AutoConnection या क्यूटी :: DirectConnection विधि का उपयोग किसी भी त्रुटि संदेश या कुछ भी नहीं मिलता है ... कहा जाता हो जाता है:

यह मैं क्या उपयोग कर रहा हूँ है , लेकिन पाठ्यक्रम के एक ही धागे से। जीयूआई थ्रेड से नहीं, जो मुझे चाहिए।

draw_widgets टाइप void draw_widgets() का सार्वजनिक स्लॉट है और मेरी कक्षा QObject को प्राप्त करती है और Q_OBJECT मैक्रो का भी उपयोग करती है।

मैं इस पर किसी भी मदद की सराहना करता हूं, या यह जांचने के लिए कि विधि को क्यों नहीं कहा जा रहा है।

धन्यवाद।

+0

मैं एक ऐसी ही स्थिति है : मेरे पास एक कक्षा है जो QObject से विरासत में है और 'Q_OBJECT' का उपयोग करती है। इस वर्ग का उदाहरण मुख्य पाश में बनाया गया है। फिर, मुख्य लूप में एक ही कक्षा की विधि को निष्पादित करते समय, मैं 'QMetaObject :: invokeMethod (यह," hideListsSlot ", Qt :: QueuedConnection) को कॉल करता हूं; ', जहां' void hideListsSlot() 'का सार्वजनिक स्लॉट है कक्षा। स्लॉट कभी नहीं बुलाया जाता है। – Giorgio

उत्तर

10

"सत्य" आपको बता रहा है कि संदेश सफलतापूर्वक कतारबद्ध किया गया था। इसका मतलब यह नहीं है कि कतारबद्ध संदेश कभी संसाधित किया गया था ...

हमें बताएं कि आपके प्रोग्राम में 10 धागे (थ्रेड 1-थ्रेड 10) हैं। आप थ्रेड 7 से एक संदेश कतारबद्ध करते हैं। यह किस धागे को कतारबद्ध किया जाएगा? और इस कतार पर वस्तुओं को कब संसाधित किया जाएगा?

उत्तर यह है कि प्रत्येक QObject में Thread Affinity नामक कुछ है, और यह वह धागा है जहां एक कतारबद्ध स्लॉट चलाया जाएगा। डिफ़ॉल्ट आत्मीयता (लेकिन आप QObject::moveToThread() साथ बदल सकते हैं।)

आप जीयूआई धागा करने के लिए कुछ क़तार में चाहते हैं, तो वस्तु अपने this सूचक द्वारा निर्दिष्ट जीयूआई धागा की होनी चाहिए धागा जहां किसी चीज़ का बनाया गया था करने के लिए है आत्मीयता। आप इसे QObject::thread() विधि से देख सकते हैं।

लेकिन किसी भी मामले में, कोई फर्क नहीं पड़ता कि आप किस धागे को कतार में रखते हैं ... आपके पास उस धागे पर चलने वाले किसी प्रकार का संदेश पंप होना चाहिए। उदाहरण के लिए QThread::exec() देखें। यदि आपका धागा संबंध जीयूआई के लिए है तो संभवतः यह पहले से ही मामला है क्योंकि आप ऐप के निष्पादन चला रहे हैं।

(एक sidenote के रूप, QMetaObject::invokeMethod के लिए सीधी कॉल आमतौर पर अनावश्यक हैं। आप एक संकेत बना सकते हैं और एक स्लॉट में जोड़ देते हैं सकता है, तो आह्वान के एवज में संकेत फेंकना।)

+0

आपके उत्तर के लिए बहुत बहुत धन्यवाद। मुझे थ्रेड एफ़िनिटी के बारे में पता नहीं था। वस्तु के एफ़िनिटी को जीयूआई थ्रेड में बदलने से समस्या हल हो गई। –

+0

@ होस्टाइलफ़ोर के विपरीत sidenote, यदि आपके पास बहुत सारे स्लॉट हैं, तो इसे स्लॉट के समान सिग्नल बनाए जाएंगे, इसलिए इस मामले में यह 'QMetaObject :: invokeMethod (यह, "स्लॉट 1 ... n" का उपयोग करने के लिए पर्याप्त है, क्यूटी :: QueuedConnection) '। –

+0

@ sostileFork विपरीत sidenote जारी है, 'invokeMethod' कॉल shoud स्थिति के अंदर स्लॉट में धक्का दिया जा सकता है 'अगर (QThread :: currentThread()! = Thread())'। इस तरह से, ग्राहक स्लॉट को सीधे कॉल कर सकते हैं। –

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