第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

帶有瀏覽按鈕的自定義項(xiàng)目委托的 QTreeView

帶有瀏覽按鈕的自定義項(xiàng)目委托的 QTreeView

Cats萌萌 2022-07-26 15:59:32
使用 Qt5 框架(通過 Python 的 pyQt5),我需要?jiǎng)?chuàng)建一個(gè)帶有參數(shù) - 值列的 QTreeView 小部件,其中某些行的值項(xiàng)必須具有內(nèi)部“瀏覽”按鈕以打開文件瀏覽對(duì)話框并放置選定的文件到相應(yīng)值的字段中。閱讀關(guān)于項(xiàng)目委托的 Qt 手冊(cè),我整理了以下代碼:自定義 BrowseEdit 類(QLineEdit + Browse 操作)class BrowseEdit(QtWidgets.QLineEdit):    def __init__(self, contents='', filefilters=None,        btnicon=None, btnposition=None,        opendialogtitle=None, opendialogdir=None, parent=None):        super().__init__(contents, parent)        self.filefilters = filefilters or _('All files (*.*)')        self.btnicon = btnicon or 'folder-2.png'        self.btnposition = btnposition or QtWidgets.QLineEdit.TrailingPosition        self.opendialogtitle = opendialogtitle or _('Select file')        self.opendialogdir = opendialogdir or os.getcwd()        self.reset_action()    def _clear_actions(self):        for act_ in self.actions():            self.removeAction(act_)    def reset_action(self):        self._clear_actions()        self.btnaction = QtWidgets.QAction(QtGui.QIcon(f"{ICONFOLDER}/{self.btnicon}"), '')        self.btnaction.triggered.connect(self.on_btnaction)        self.addAction(self.btnaction, self.btnposition)        #self.show()    @QtCore.pyqtSlot()    def on_btnaction(self):        selected_path = QtWidgets.QFileDialog.getOpenFileName(self.window(), self.opendialogtitle, self.opendialogdir, self.filefilters)        if not selected_path[0]: return        selected_path = selected_path[0].replace('/', os.sep)        # THIS CAUSES ERROR ('self' GETS DELETED BEFORE THIS LINE!)        self.setText(selected_path)QTreeView 的自定義項(xiàng)目委托:class BrowseEditDelegate(QtWidgets.QStyledItemDelegate):    def __init__(self, model_indices=None, thisparent=None,                 **browse_edit_kwargs):        super().__init__(thisparent)        self.model_indices = model_indices        self.editor = BrowseEdit(**browse_edit_kwargs)          self.editor.setFrame(False)      
查看完整描述

1 回答

?
侃侃爾雅

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超16個(gè)贊

每個(gè)代表不能只有一個(gè)唯一的編輯器,原因有兩個(gè):

  1. 可能有更多的編輯器的活動(dòng)實(shí)例(使用 打開openPersistentEditor),例如一個(gè)表,其中一列的每一行都有一個(gè)組合框。

  2. 每次編輯器將其數(shù)據(jù)提交給模型時(shí),如果它不是持久編輯器,它就會(huì)被銷毀??紤]當(dāng)一個(gè) Qt 對(duì)象被分配給一個(gè) Python 變量/屬性時(shí),它實(shí)際上是一個(gè)指向由 Qt 創(chuàng)建的底層 C++ 對(duì)象的指針。這意味著雖然self.editor仍然作為 python 對(duì)象存在,但它指向一個(gè)在編輯器被委托關(guān)閉時(shí)實(shí)際刪除的對(duì)象。

正如函數(shù)名所說,createEditor() 創(chuàng)建一個(gè)編輯器,所以解決方法是每次createEditor()調(diào)用都創(chuàng)建一個(gè)新實(shí)例。

更新

但是,這里有一個(gè)重要問題:一旦您打開對(duì)話框,委托編輯器就會(huì)失去焦點(diǎn)。對(duì)于一個(gè)項(xiàng)目視圖,這與單擊另一個(gè)項(xiàng)目(更改焦點(diǎn))相同,這將導(dǎo)致數(shù)據(jù)提交和編輯器破壞。

“簡(jiǎn)單”的解決方案是在要打開對(duì)話框時(shí)阻止委托信號(hào)(最重要的closeEditor()是會(huì)調(diào)用),然后再解除阻止。destroyEditor()

class BrowseEdit(QtWidgets.QLineEdit):

    @QtCore.pyqtSlot()

    def on_btnaction(self):

        self.delegate.blockSignals(True)

        selected_path = QtWidgets.QFileDialog.getOpenFileName(self.window(), self.opendialogtitle, self.opendialogdir, self.filefilters)

        self.delegate.blockSignals(False)

        if not selected_path[0]: return

        selected_path = selected_path[0].replace('/', os.sep)

        # THIS CAUSES ERROR ('self' GETS DELETED BEFORE THIS LINE!)

        self.setText(selected_path)



class BrowseEditDelegate(QtWidgets.QStyledItemDelegate):

    # ...

    def createEditor(self, parent: QtWidgets.QWidget, option: QtWidgets.QStyleOptionViewItem,

                    index: QtCore.QModelIndex) -> QtWidgets.QWidget:

        try:

            if self.model_indices and index in self.model_indices:

                editor = BrowseEdit(parent=parent)

                editor.delegate = self

                return editor

            else:

                return super().createEditor(parent, option, index)

        except Exception as err:

            print(err)

            return None

也就是說,這是一個(gè)hack。雖然它有效,但不能保證它會(huì)在未來版本的 Qt 中,當(dāng)可能引入其他信號(hào)或它們的行為發(fā)生變化時(shí)。


更好更優(yōu)雅的解決方案是創(chuàng)建一個(gè)在單擊瀏覽按鈕時(shí)調(diào)用的信號(hào),然后項(xiàng)目視圖(或其任何父項(xiàng))將負(fù)責(zé)瀏覽,如果文件對(duì)話框結(jié)果有效則設(shè)置數(shù)據(jù)并再次開始編輯該字段:



class BrowseEditDelegate(QtWidgets.QStyledItemDelegate):

    browseRequested = QtCore.pyqtSignal(QtCore.QModelIndex)

    # ...

    def createEditor(self, parent: QtWidgets.QWidget, option: QtWidgets.QStyleOptionViewItem,

                    index: QtCore.QModelIndex) -> QtWidgets.QWidget:

        try:

            if self.model_indices and index in self.model_indices:

                editor = BrowseEdit(parent=parent)

                editor.btnaction.triggered.connect(

                    lambda: self.browseRequested.emit(index))

                return editor

            else:

                return super().createEditor(parent, option, index)

        except Exception as err:

            print(err)

            return None



class Window(QtWidgets.QWidget):

    def __init__(self):

        # ...

        delegate = BrowseEditDelegate(indices)

        self.tv_plugins_3party.setItemDelegate(delegate)

        delegate.browseRequested.connect(self.browseRequested)


    def browseRequested(self, index):

        selected_path = QtWidgets.QFileDialog.getOpenFileName(self.window(), 'Select file', index.data())

        if selected_path[0]:

            self.model_plugins_3party.setData(index, selected_path[0])

        self.tv_plugins_3party.edit(index)


查看完整回答
反對(duì) 回復(fù) 2022-07-26
  • 1 回答
  • 0 關(guān)注
  • 219 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)