في QT ، كيف يمكنني تنفيذ عنصر واجهة مستخدم يبقى متسقًا مع المتغيرات في الكود

StackOverflow https://stackoverflow.com/questions/818981

  •  03-07-2019
  •  | 
  •  

سؤال

إليك عينة من صندوق الدوران الذي يكتب تغييراته على المتغيرات الأساسية. يتم استدعاء المشكلة الرئيسية التي أواجهها هي أنه يتم استدعاء Valuechanged عندما يتم بناء عنصر واجهة المستخدم. هل هناك طريقة أكثر أناقة للقيام بذلك؟ أعتقد أنه من الغريب أن أقوم بتوصيل عنصر واجهة مستخدم لنفسه ، لكن Valuechanged ليست افتراضية.

class ValueWriterInt: public QSpinBox {
    Q_OBJECT

public:
    ValueWriterInt(vector<int*> const& value): myValue(value) { 
        QObject::connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
    }
    ~ValueWriterInt() {}

private slots:
    void    valueChanged(int new_value) {
        for (auto it = myValue.begin(); it != myValue.end(); ++it)
            **it = new_value;
    }

private:
    vector<int*>        myValue;
};
هل كانت مفيدة؟

المحلول

لا أرى شيئًا غريبًا بشكل خاص حول توصيل عنصر واجهة مستخدم لنفسه. يبدو أن وجود طريقة واحدة لاكتشاف تحديثات البيانات والاستجابة لها أمرًا جيدًا في الواقع لأن لديك نقاطًا أقل من الفشل في التحقق عند تصحيح الأخطاء. في حالتك المحددة ، يسبب بعض السلوك غير المرغوب فيه ، ولكن بشكل عام هو حل جيد.

الآن ، بعد أن أعرب عن رأي مفاده أن العلاقة الانعكاسية ليست غير متضخمة بطبيعتها ، سأقترح حلاً أقل من "أنيقة" لمنع دعوة valueChanged بعد البناء. يمكنك الحصول على علامة لتحديد ما إذا كان الكائن قد تم بناؤه فقط والعودة مبكرًا لمنع تشغيل الكود فور البناء. في مثالك:

class ValueWriterInt: public QSpinBox {
Q_OBJECT

public:
    ValueWriterInt(vector<int*> const& value): myValue(value), myAfterInit(true) { 
        QObject::connect(this, SIGNAL(valueChanged(int)), this, SLOT(valueChanged(int)));
    }
    ~ValueWriterInt() {}

private slots:
    void        valueChanged(int new_value) {
        if (myAfterInit) {
            myAfterInit = false;
            return;
        }
        for (auto it = myValue.begin(); it != myValue.end(); ++it)
                **it = new_value;
    }

private:
    vector<int*>                myValue;
    boolean                     myAfterInit;
};

هذا ليس سيئًا جدًا من الحل. سيعطيك على الأقل سلوكك المطلوب حتى (وإذا) يمكنك العثور على طريقة أكثر أناقة.

نصائح أخرى

إذن ما الذي تحاول إنجازه هنا؟ نعم ، فالناقل ليس افتراضيًا - لماذا يجب أن تكون ، يجب أن تتصل كائناتك مباشرة خاصة بهم فتحات إلى أي إشارات يريدون الرد عليها ، لا؟

لا أرى أي بديل آخر غير استخدام اتصالات الإشارة. ومع ذلك ، أود تغيير اسم الفتحة ، لذلك ليس له نفس اسم الإشارة.

من المثير للاهتمام كيف تسمى الفتحة حتى إذا لم يتم إجراء اتصال بعد. أظن أن تغيير اسم الفتحة سيحل هذه المشكلة.

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