4

QCheckBoxウィジェットを使用してブール変数の値を表示しようとしていますが、表示された値をユーザーが変更できないようにしています。結果として生じる灰色が見栄えが悪いため、無効にしたくありません。ユーザーがQCheckBox. ただし、ウィジェットの状態がQAbstractButton親クラスの「チェック済み」プロパティとQCheckBoxクラス自体の「状態」プロパティによって記述されるという事実によって、問題はさらに複雑になります。これにより、シグナルとスロットの組み合わせの演習が発生しますが、良い結果を得ることができませんでした。

var_ctrl = QtGui.QCheckBox( 'some name' )

def rdslot1(state): 
    if state == QtCore.Qt.Checked:
        var_ctrl.setCheckState( QtCore.Qt.Unchecked )
    else:                               
        var_ctrl.setCheckState( QtCore.Qt.Checked )

def rdslot2(state): 
    if var_ctrl.isChecked():
        var_ctrl.setChecked(False)
    else:
        var_ctrl.setChecked(True)

# Signal/Slot combinations (only one should be active)
var_ctrl.stateChanged.connect( rdslot1 )
var_ctrl.toggled.connect( rdslot2 )
var_ctrl.stateChanged.connect( rdslot2 )
var_ctrl.toggled.connect( rdslot1 )
4

3 に答える 3

4

私はパーティーに遅れました - あなたはうまくいく解決策を手に入れたようです. 今後の参考のために、マウスイベントを消費する別の方法があります。これにより、すべてのシグナルが正常に機能し続けます。

from PyQt4 import QtGui, QtCore

class MyCheckBox(QtGui.QCheckBox):
    def __init__( self, *args ):
        super(MyCheckBox, self).__init__(*args) # will fail if passing **kwargs
        self._readOnly = False

    def isReadOnly( self ):
        return self._readOnly

    def mousePressEvent( self, event ):
        if ( self.isReadOnly() ):
            event.accept()
        else:
            super(MyCheckBox, self).mousePressEvent(event)

    def mouseMoveEvent( self, event ):
        if ( self.isReadOnly() ):
            event.accept()
        else:
            super(MyCheckBox, self).mouseMoveEvent(event)

    def mouseReleaseEvent( self, event ):
        if ( self.isReadOnly() ):
            event.accept()
        else:
            super(MyCheckBox, self).mouseReleaseEvent(event)

    # Handle event in which the widget has focus and the spacebar is pressed.
    def keyPressEvent( self, event ):
        if ( self.isReadOnly() ):
            event.accept()
        else:
            super(MyCheckBox, self).keyPressEvent(event)

    @QtCore.pyqtSlot(bool)
    def setReadOnly( self, state ):
        self._readOnly = state

    readOnly = QtCore.pyqtProperty(bool, isReadOnly, setReadOnly)

このようにコードを設定すると、いくつかのことが得られます (気にする場合と気にしない場合があります) が、カスタム Qt ウィジェットを開発するときに役立ちます。

  1. イベントを消費すると信号の放出がブロックされるため、他のスロットをクリックやトグルなどに接続できます。これらのシグナルを探していて、値のオン/オフを切り替えるだけの場合、それらのシグナルをリッスンしている他のウィジェットが正しくトリガーされません。
  2. isReadOnly/setReadOnly を使用すると、Qt コーディング スタイルに従ってクラスを維持できます
  3. pyqtSignals と pyqtSlots を作成すると、プラグインを Qt のデザイナーに公開する場合に役立ちます
于 2012-08-01T16:48:42.990 に答える
1

かなり後で、ユーザーのクリックをキャッチし、指定可能な「変更可能」プロパティに従ってそれらを処理するショートカットを思いつきました。私はこのクラスを作りました:

class MyQCheckBox(QtGui.QCheckBox):

    def __init__(self, *args, **kwargs):
        QtGui.QCheckBox.__init__(self, *args, **kwargs)        
        self.is_modifiable = True
        self.clicked.connect( self.value_change_slot )

    def value_change_slot(self): 
        if self.isChecked():
            self.setChecked(self.is_modifiable)
        else:
            self.setChecked(not self.is_modifiable)            

    def setModifiable(self, flag):
        self.is_modifiable = flag            

    def isModifiable(self):
        return self.is_modifiable

通常のように動作しQCheckBox、デフォルトで変更可能です。ただし、を呼び出すとsetModifiable(False)、クリックするたびに、ウィジェットの現在の状態が保持されます。秘訣はclicked信号をキャッチすることであり、toggledどちらでもないstateChanged

于 2012-07-13T14:37:26.293 に答える
1

チェックボックス ウィジェットを無効にしてみてください。ただし、ウィジェットパレットまたはスタイルを使用して外観をオーバーライドします。

于 2012-07-13T15:08:50.320 に答える