2009-12-06 11 views
6

¿Falto algo o realmente no hay (listo/incorporado) forma de cambiar programáticamente el estado de un QCheckBox sin emitir la señal "estado vacíoCambiado (estado int)"?QCheckBox: ¿cómo diferenciar entre los cambios de estado inducidos por el usuario y los realizados programáticamente?

La señal antes mencionada se emite independientemente de si se llamó "void setCheckState (Qt :: CheckState state)" o el usuario cambió el estado a través del ui, y no hay señal "stateEdited" como con el QLineEdit.

Por lo tanto, si no hay una forma fácil de diferenciar entre cambios programáticos y los inducidos por el usuario al estado de QCheckBox, y las únicas opciones son subclasar/agregar la señal "stateEdited" o tocar "void QObject :: blockSignals (bool block) ", ¿por qué tiene que ser así, es decir, es una (alguna clase de) inconsistencia (en Qt)?

Respuesta

13

Si sólo necesita ser informado de la entrada del usuario, escuchar

QAbstractButton::clicked(bool checked); 

De lo contrario conectarse a

QAbstractButton::toggled(bool checked); 

o

QCheckBox::stateChanged(int state); 
+0

¡Esa es la única, gracias! – mlvljr

1

Si desea

programáticamente cambiar el estado de un QCheckBox

uso setCheckState método.

P.S. No entiendo qué significa

cambiar el estado de un QCheckBox ... que emite una señal de "vacío stateChanged (estado int)"

Probablemente usted debe leer Signals and Slots tema con más cuidado.

+0

Significa que mi inglés es MALO :) y también lo siguiente: 1) llama a setCheckState (...) 2) "void stateChanged (int state)" no se emite. En otras palabras, estoy interesado en un comportamiento como el de QLineEdit. Citando la documentación de Qt: "void QLineEdit :: textEdited (const QString & text) [signal] ... A diferencia de textChanged(), esta señal no se emite cuando el texto se cambia programáticamente, por ejemplo, llamando a setText()." – mlvljr

+0

Entiendo tu punto.Solo veo una opción: crear y usar en lugar de la clase QCheckBox tu propia clase que se basa en QCheckBox (subclase) y luego definir un nuevo método (o volver a establecer el conjunto de comprobado). Su método debe diferir de uno de QCheckBox (http://qt.gitorious.org/qt/qt/blobs/master/src/gui/widgets/qcheckbox.cpp) solo en la última línea de código. No es necesario emitir stateChanged (estado); Pero no creo que sea una buena solución ... ¿Por qué necesita un comportamiento tan diferente? – Wildcat

+0

Parece que hay una necesidad de configurar algunos widgets cuyas señales ya están conectadas sin emitirlas (señales). De todos modos, siempre puedo usar "QObject :: blockSignals (bool block)". PD (off.) Tu página web en está en ruso, ¿de verdad eres de allí? – mlvljr

9

Un método que funciona para todas las señales y widgets es para envolver las llamadas a setChecked() en un par de llamadas blockSignals():

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

o, con algo que cada programador Qt tendrá en su caja de herramientas:

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

una clase RAII. Uso:

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

EDITAR 10/12/2013: Qt 5.3 tendrá QSignalBlocker incorporado.

+2

No soy un OP, pero una gran respuesta, gracias. – ttvd

Cuestiones relacionadas