3

QLabels と QLineEdits を並べて含む QWidget があります。

QLabel をクリックすると、QWidget で mousePressEvent を使用できます。しかし、QLineEdit をクリックすると、QWidget で mousePressEvent を検出できません - QLineEdit でのみです。QLineEdit の動作に関係していると思います。領域全体でマウス イベントを取得する方法がわかりません。

編集

ここに画像の説明を入力

上記のような Maya 用のカスタム チャネル ボックスを作成しました。マウスをドラッグして複数のチャンネルを選択しようとしています。しかし、前述したように、QLineEdit 領域ではこれを行うことができません。

class channelWidget(QtGui.QWidget):
  def __init__(self, parent=None):
    super(channelWidget, self).__init__(parent)
    self.resize(180, 20)        
    self.setMinimumSize(180, 20)
    self.setMaximumHeight(20)
    self.attr_label = QtGui.QLabel(self)
    self.attr_label.setGeometry(QtCore.QRect(5, 0, 110, 20))
    self.attr_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
    self.value_field = focusLineEdit(self)
    self.value_field.setGeometry(QtCore.QRect(120, 0, 60, 20))
    self.value_field.setAlignment(QtCore.Qt.AlignLeft|QtCore.Qt.AlignLeading|QtCore.Qt.AlignVCenter)
    self.value_field.setValidator(QtGui.QDoubleValidator())

各要素は、QLabel と QLineEdit で構成されます。

class channelContainerWidget(QtGui.QWidget):
  def updateChannel(self, node="", attrList=[]):
    _l = self.channel_layout
    _list = []
    for w in [_l.itemAt(i).widget() for i in range(_l.count()) if _l.itemAt(i).widget()]:
      if w in self._selectList: _list.append( str( w.attr_label.text() ) )
        sip.delete(w)

    _selList = []
    for _id, at in enumerate(attrList):
      _item = channelWidget(self)
      _item.attr_label.setText(at)
      _item.value_field.setText(value)
      _l.insertWidget(_id, _item)

そして、含まれているウィジェットは上記のように機能します。QLabel 領域をクリックするとマウス イベントを取得できますが、QLineEdit 領域をクリックすると取得できません。

4

1 に答える 1

3

mousePressEvent()レイアウトを含むメイン ウィジェットからを見ている場合、 のクリックが表示されるのQLabelは、デフォルトで が をQLabel無視しmousePressEvent、次の親にバブル アップできるためです。イベントは、子から親へと上向きに伝播します。

ただし、ライン編集ウィジェットに共通するフォーカスやその他のさまざまなアクションを処理するには、マウスの押下を受け入れて使用するQLineEdit必要があります。

したがって、本当に良いオプションは、イベント フィルターを使用することです。これにより、メインのウィジェットが他のウィジェットのイベントを監視できるようになり、サブクラス化しQLineEditて実装する必要がなくなります。mousePressEvent

この例では、単にレイアウトのメンバーとマウスの押下を監視し、印刷してから、何も変更しないデフォルト アクションを実行します。

class Widget(QtGui.QWidget):

    def __init__(self):
        super(Widget, self).__init__()

        self.layout = QtGui.QHBoxLayout(self)

        self.label = QtGui.QLabel("Label")
        self.line = QtGui.QLineEdit()

        self.layout.addWidget(self.label)
        self.layout.addWidget(self.line)        

        # have this widget (self) watch events for these    
        self.label.installEventFilter(self)
        self.line.installEventFilter(self)

    def mousePressEvent(self, event):
        print "Main Widget Mouse Press"
        super(Widget, self).mousePressEvent(event)

    def eventFilter(self, obj, event):
        # you could be doing different groups of actions
        # for different types of widgets and either filtering
        # the event or not.
        # Here we just check if its one of the layout widgets
        if self.layout.indexOf(obj) != -1:
            if event.type() == event.MouseButtonPress:
                print "Widget click", obj
                # if I returned True right here, the event
                # would be filtered and not reach the obj,
                # meaning that I decided to handle it myself

        # regardless, just do the default
        return super(Widget, self).eventFilter(obj, event)

このコードをテストすると、ラベルをクリックすると、メイン ウィジェットとそのイベント フィルターの両方で印刷が行われることがわかります。ただし、行の edit をクリックすると、イベント フィルターの print ステートメントのみが発生しますmousePressEvent

于 2012-12-14T02:13:46.303 に答える