Wie kann ich in QT ein Widget implementieren, das mit Variablen im Code übereinstimmt?

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

  •  03-07-2019
  •  | 
  •  

Frage

Hier ist ein Beispiel einer Spinbox, die seine Änderungen an zugrunde liegenden Variablen schreibt. Das Hauptproblem, das ich habe, ist wertschöpfend, wenn das Widget konstruiert ist. Gibt es eine elegantere Möglichkeit, dies zu tun? Ich denke, es ist seltsam, dass ich ein Widget mit sich selbst verbunden habe, aber ValaThanged ist nicht virtuell.

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;
};
War es hilfreich?

Lösung

Ich sehe nichts besonders Seltsames, wenn ich ein Widget mit sich selbst verbindet. Eine einzige Methode zum Erkennen und Reagieren auf Datenaktualisierungen klingt tatsächlich nach einer guten Sache, da Sie weniger Punkte haben, bei denen Sie beim Debuggen nicht überprüft werden. In Ihrem speziellen Fall verursacht es ein unerwünschtes Verhalten, ist jedoch im Allgemeinen eine gute Lösung.

Nachdem ich nun die Meinung zum Ausdruck gebracht habe, dass eine reflexive Verbindung nicht von Natur aus unelegant ist, werde ich eine weniger als "elegante" Lösung vorschlagen, um die Berufung zu verhindern valueChanged nach dem Bau. Sie können ein Flag haben, um festzustellen, ob das Objekt gerade konstruiert wurde, und frühzeitig zurückkehren, um zu verhindern, dass der Code unmittelbar nach dem Bau ausgeführt wird. In Ihrem Beispiel:

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;
};

Das ist eine Lösung nicht schlecht. Es gibt Ihnen zumindest Ihr gewünschtes Verhalten, bis Sie eine elegantere Methode finden.

Andere Tipps

Was versuchen Sie hier zu erreichen? Ja, ValaTechanged ist nicht virtuell - warum sollte es sein, dass Ihre Objekte direkt eine Verbindung herstellen sollten ihre eigenen Slots zu den Signalen, auf die sie reagieren wollen, nein?

Ich sehe keine andere Alternative, als Signal-Slot-Verbindungen zu verwenden. Ich würde jedoch den Namen des Steckplatzes ändern, sodass er nicht den gleichen Namen wie das Signal hat.

Es ist faszinierend, wie der Steckplatz genannt wird, auch wenn noch keine Verbindung hergestellt wird. Ich vermute, dass das Ändern des Namens des Steckplatzes dieses Problem lösen wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top