0

私がしばらくの間戦ってきたこの厄介な問題を誰かが助けてくれることを願っています. デリゲート列のテーブルビューにボタンを挿入するために添付されたコードで管理しました。

問題は、ボタンを押すには、含まれているセルをダブルクリックして「アクティブ化」する必要があることです。セルがアクティブになると、ボタンを押すことができるので、合計で 3 回クリックして押す必要があります。これは、平均的なユーザーにとって混乱を招く可能性があります。

この問題を pyqt メーリング リストに投稿したところ、次のような回答が得られました。

「何が起こるかというと、TableWidget がクリックを受け取るとエディターが作成されますが、エディターはまだクリックを受け取っていません。ほとんどの場合、これで完璧ですが、ボタンを描画する場合はそうではありません。」

誰かここに来たことがありますか?

前もって感謝します、クリス

class AnimLinkButtons(QtGui.QStyledItemDelegate):
    mouse_isPressed = False

    def __init__(self, parent = None):
        QtGui.QStyledItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        column = index.column()
        button = QtGui.QPushButton(parent)
        button.setText(self.text(index))
        ButtonLoc = self.ButtonLocation(option)
        button.setGeometry(ButtonLoc)
        Cellvalue = index.model().data(index, QtCore.Qt.EditRole)
        row = index.row()
        AssetId = index.model().data(index.model().index(row, 0)).toString()

        AnimTurntablePath = shotsGetData.getAssetTurntablePath(AssetId)
        browsePath = shotsGetData.getAssetPath(AssetId)
        #toAvidComp = shotsGetData.gettoAvidComp(ShotId)

        # Connect to button
        button.clicked.connect(lambda: self.mousePressEvent(index, browsePath, AssetTurntablePath))
        return button

    def setEditorData(self, editor, index):
        button = editor
        if not button:
            return

    def setModelData(self, editor, model, index):
        button = editor
        if not button:
            return

    def updateEditorGeometry(self, editor, option, index):
        ButtonLoc = self.ButtonLocation(option)
        editor.setGeometry(ButtonLoc)

    def paint(self, painter, option, index):
        opt = QtGui.QStyleOptionButton()
        #opt.icon = self.icon()
        opt.text = self.text(index)
        opt.rect = option.rect
        opt.palette = option.palette
        opt.rect = self.ButtonLocation(opt)
        QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_PushButton, opt, painter)

    def ButtonLocation(self,  option):
        r = option.rect
        x = r.left() + 10
        y = r.top() + 10
        w = 30;
        h = 30
        return QRect(x,y,w,h);

    def text(self,  index):
        #print self.column
        column = index.column()
        if column == 7:
            return QtCore.QString("Mov")


    def mousePressEvent(self, index, browsePath , AssetTurntablePath):
        column = index.column()
        print "PRESSSED"

        if column == 7:
            subprocess.Popen(AnimTurntablePath, shell=True)
4

2 に答える 2

4

最近、似たようなものを作りました。でボタンを作成した場合createEditorは、編集モードでアクティブにします。これは、セルをダブルクリックすると発生します。したがって、メーリングリストからのコメントは正しいです。

編集せずにそれを行うのは難しいです。メソッドでペイントしたボタンpaintは単なる絵であり、実際のボタンではありません。editorEventマウス イベントを監視する必要があります。この目的のためにイベントをキャプチャmouseButtonPressします。mouseButtonRelease

さらに、ボタンをクリックしたときの「視覚的な」効果が必要な場合は、事態が複雑になります。とにかく、以下は基本的な実装です。とでbuttonClicked信号を発します。rowcolumn

: 再描画は、デリゲートが他の列からもイベントを受け取るという事実に依存しています。で使用すると、デリゲートはその列からのみイベントを受け取るため、これはおそらく適切に機能しません。setItemDelegateForColumnしたがって、テーブル全体に使用し、列に従ってペイントすることをお勧めします。

class ButtonDelegate(QtGui.QStyledItemDelegate):
    buttonClicked = QtCore.pyqtSignal(int, int)

    def __init__(self, parent = None):
        super(ButtonDelegate, self).__init__(parent)
        self._pressed = None

    def paint(self, painter, option, index):
        painter.save()
        opt = QtGui.QStyleOptionButton()
        opt.text = index.data().toString()
        opt.rect = option.rect
        opt.palette = option.palette
        if self._pressed and self._pressed == (index.row(), index.column()):
            opt.state = QtGui.QStyle.State_Enabled | QtGui.QStyle.State_Sunken
        else:
            opt.state = QtGui.QStyle.State_Enabled | QtGui.QStyle.State_Raised
        QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_PushButton, opt, painter)
        painter.restore()

    def editorEvent(self, event, model, option, index):
        if event.type() == QtCore.QEvent.MouseButtonPress:
            # store the position that is clicked
            self._pressed = (index.row(), index.column())
            return True
        elif event.type() == QtCore.QEvent.MouseButtonRelease:
            if self._pressed == (index.row(), index.column()):
                # we are at the same place, so emit
                self.buttonClicked.emit(*self._pressed)
            elif self._pressed:
                # different place.
                # force a repaint on the pressed cell by emitting a dataChanged
                # Note: This is probably not the best idea
                # but I've yet to find a better solution.
                oldIndex = index.model().index(*self._pressed)
                self._pressed = None
                index.model().dataChanged.emit(oldIndex, oldIndex)
            self._pressed = None
            return True
        else:
            # for all other cases, default action will be fine
            return super(ButtonDelegate, self).editorEvent(event, model, option, index)
于 2013-02-01T11:47:38.277 に答える