2013-04-02 19 views
7

पर सेट किए जाने पर क्यूटी संकेतों को दबाने का सही तरीका क्या है I QWidget व्युत्पन्न कक्षा से प्राप्त हुआ जिसमें तीन QSpinBoxes (उदा। निर्देशांक) हैं। valueChanged() संकेत से जुड़ा हुआ है और कम से कम इन तीन मामलों में उत्सर्जित होता है:मूल्यों को स्पष्ट रूप से

  1. ऊपर/नीचे बटन
  2. मैन्युअल रूप से दर्ज संख्या
  3. setValue()

हालांकि, जब setValue() का उपयोग कर, मैं चाहता हूँ सिग्नल को दबाएं, क्योंकि मैं (तीन) सिग्नल नहीं चाहता हूं। मेरी समझ में, वहाँ इस संभाल करने के लिए दो तरीके हैं:

  1. QObject::blockSignals()
  2. एक ध्वज है कि इंगित करता है मूल्यों पर स्पष्ट रूप स्थापित किया गया है कि क्या

दोनों काम वेरिएंट का उपयोग कर, लेकिन मुझे लगता है कि वे सीधे नहीं हैं बिल्कुल भी: पहले के लिए, मैं आम तौर पर सभी संकेतों को अवरुद्ध करता हूं और मुझे सभी अंडरलिंग विगेट्स के लिए blockSignals(true) सेट करने की आवश्यकता है (ब्लॉक सिग्नल मेरे आवेदन में बच्चों को QObjects को अवरुद्ध नहीं करता है)। दूसरे के लिए, मुझे प्रत्येक अद्यतन विधि में ध्वज से पूछताछ करने की आवश्यकता है और संकेत उठाए गए हैं हालांकि मुझे उनकी आवश्यकता नहीं है।

क्या कोई सामान्य डिजाइनिंग पैटर्न है जो इस तरह के व्यवहार को रोकता है? यदि नहीं, तो आप किस संस्करण को पसंद करेंगे?

उत्तर

4

तीसरा विकल्प QSpinBox उपवर्ग के लिए हो सकता है, वहाँ वांछित लागू कार्यक्षमता, और QSpinBox के बजाय वर्ग व्युत्पन्न का इस्तेमाल किया - यह खाल व्युत्पन्न वर्ग में सभी संबद्ध जटिलता और आप यह सिर्फ QSpinBox की तरह उपयोग करने की अनुमति देता है।

उदाहरण के लिए

, वर्ग

myQSpinBox.h

#ifndef MYQSPINBOX_H 
#define MYQSPINBOX_H 

#include <QSpinBox> 

class myQSpinBox : public QSpinBox 
{ 
    Q_OBJECT 
public: 
    myQSpinBox(QWidget * parent = 0); 
protected: 
    bool valueBeingSet; 
public slots: 
    void setValue (int val); 
private slots: 
    void On_valueChanged(int val); 
signals: 
    void valueChangedNotBySet(int val); 
}; 

#endif // MYQSPINBOX_H 

myQSpinBox.cpp

#include "myQSpinBox.h" 

myQSpinBox::myQSpinBox(QWidget * parent) 
     : QSpinBox(parent) 
     , valueBeingSet(false) 
{ 
    connect(this,SIGNAL(valueChanged(int)),this,SLOT(On_valueChanged(int))); 
} 

void myQSpinBox::setValue (int val) 
{ 
    valueBeingSet = true; 
    QSpinBox::setValue(val); 
    valueBeingSet = false; 
} 

void myQSpinBox::On_valueChanged(int val) 
{ 
    if(!valueBeingSet) 
     emit valueChangedNotBySet(val); 
} 

मामलों 1. और 2., लेकिन मामले 3 में नहीं में valueChangedNotBySet(int); उत्सर्जित करेगा निम्नलिखित। , सभी QSpinBox कार्यक्षमता को बरकरार रखते हुए

+0

अरे Ilya, धन्यवाद। आप बिल्कुल सही हैं - यह तीसरा (और अब तक का सबसे साफ) संस्करण है। हालांकि, मुझे सभी प्रकार के विगेट्स (एक बार) को फिर से लागू करने की आवश्यकता होगी (क्यूएसपीनबॉक्स सिर्फ एक उदाहरण था) - QLineEdit, QComboBox, QDoubleSpinBox, ...। – braggPeaks

+0

मुझे यकीन नहीं है कि QLineEdit को फिर से कार्यान्वित करने की आवश्यकता है - चूंकि QLineEdit में सिग्नल टेक्स्ट हैं (कॉन्स्ट क्यूस्ट्रिंग और टेक्स्ट) और टेक्स्ट एडिट (कॉन्स क्यूस्ट्रिंग और टेक्स्ट) जो संपादन के प्रकारों के बीच अंतर करने की अनुमति देता है। QComboBox पर भी लागू हो सकता है ... –

+1

यह केवल तभी काम करेगा जब यूआई थ्रेड में सबकुछ होता है। एकाधिक थ्रेड में सिग्नल/स्लॉट कनेक्शन की श्रृंखला होने पर, 'valueBeingSet' को 'valueChnaged' सिग्नल फिर से उत्सर्जित होने से पहले' गलत 'पर सेट किया जाएगा, क्योंकि ईवेंट हैंडलर को असीमित रूप से कहा जाएगा। – fferri

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