2009-12-06 5 views
6

Vermisse ich etwas oder gibt es wirklich keine (bereit/eingebaute) Möglichkeit, den Status einer QCheckBox programmgesteuert zu ändern, ohne das Signal "void stateChanged (int state)" auszugeben?QCheckBox: Wie unterscheidet man zwischen benutzerinduzierten Statusänderungen und programmgesteuerten?

Das oben erwähnte Signal wird unabhängig davon ausgegeben, ob "void setCheckState (Qt :: CheckState state)" aufgerufen wurde oder der Benutzer den Status über das ui geändert hat und es kein "stateEdited" -Signal wie bei QLineEdit gibt.

Also, wenn es keine Möglichkeit gibt, zwischen programmatischen und benutzerinduzierten Änderungen am Status der QCheckBox zu unterscheiden, und die einzigen Optionen sind Unterklassenbildung/Hinzufügen des "stateEdited" -Signals oder Fiedeln mit "void QObject :: blockSignals (Bool Block) ", warum muss das so sein, dh, ist es eine (eine Art) Inkonsistenz (in Qt)?

Antwort

13

Wenn Sie nur von Benutzereingaben informiert werden, schließen

QAbstractButton::clicked(bool checked); 
zu

hören

Andernfalls

QAbstractButton::toggled(bool checked); 

oder

QCheckBox::stateChanged(int state); 
+0

Das ist der, danke! – mlvljr

1

Wenn Sie wollen

programmatisch den Zustand eines QCheckBox ändern

Verwendung setCheckState Methode.

P.S. Ich verstehe nicht, was es bedeutet

Änderung der Zustand eines QCheckBox ... eine „Leere statechanged (int state)“ Signal

Wahrscheinlich emittieren sollten Sie Signals and Slots Thema mehr sorgfältig lesen.

+0

Es bedeutet, dass mein Englisch ist BAD :) und auch das folgende: 1) Sie rufen setCheckState (...) 2) "void stateChanged (int state)" wird nicht emittiert. Mit anderen Worten, ich bin an einem Verhalten wie dem von QLineEdit interessiert. Zitat QT-Dokumentation: "void QLineEdit :: textEdited (const QString & Text) [Signal] ... Im Gegensatz zu textChanged() wird dieses Signal nicht ausgegeben, wenn der Text programmgesteuert geändert wird, zum Beispiel durch den Aufruf von setText()." – mlvljr

+0

Ich verstehe Ihren Standpunkt.Ich sehe nur eine Option: Erstelle und benutze statt QCheckBox-Klasse deine eigene Klasse, die auf QCheckBox basiert (Unterklasse it) und dann neue Methode definiere (oder redifine setChecked). Ihre Methode sollte nur in der letzten Codezeile von einer der QCheckBox (http://qt.gitorious.org/qt/qt/blobs/master/src/gui/widgets/qcheckbox.cpp) abweichen. Sie brauchen nicht emit stateChanged (state); Aber ich denke nicht, dass es eine gute Lösung ist ... Warum brauchen Sie so unterschiedliche Verhaltensweisen? – Wildcat

+0

Es scheint notwendig zu sein, einige Widgets einzurichten, deren Signale bereits verbunden sind, ohne sie zu senden (Signale). Wie auch immer, ich kann immer "QObject :: blockSignals (bool block)" verwenden. P.S. (off.) Ihre Webseite unter ist auf Russisch, sind Sie wirklich von dort? – mlvljr

9

Ein Ansatz, der für alle Signale arbeitet und Widgets ist es, die Anrufe zu setChecked() in einem Paar von blockSignals() Anrufe:

const bool blocked = but->signalsBlocked(); 
but->blockSignals(true); 
but->setChecked(true); 
but->blockSignals(blocked); 

oder, mit etwas wird jeder Qt-Programmierer in seinem Werkzeugkasten haben:

class QSignalBlocker { 
    QObject * const o; 
    const bool blocked; 
public: 
    explicit QSignalBlocker(QObject * o) 
     : o(o), 
     blocked(o && o->signalsBlocked()) 
    { 
     if (o) o->blockSignals(true); 
    } 
    ~QSignalBlocker() { if (o) o->blockSignals(blocked); } 
}; 

eine RAII Klasse. Verbrauch:

const QSignalBlocker blocker(but); 
but->setChecked(true); 

EDIT 2013.12.10: Qt 5.3 wird QSignalBlocker eingebaut.

+2

Ich bin nicht OP, aber gute Antwort, danke. – ttvd

Verwandte Themen