简体   繁体   中英

How to set an item to being edited from a button click in PyQt5

I am trying to create a "Rename" button in a GUI I've been working on. When this button is clicked, I want the selected item to go into "Edit mode", where you can type a new name.

I have gotten to the point where everything works, but I don't know how to set the flags properly in order to go into edit mode from the index. Below is a working standalone example.

In this example, if I have selected the item I want to edit, and press F2, then it goes into edit mode. I want to achieve the same thing when I click the "Rename" button.

class MainWindow(QMainWindow):

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

        self.main_widget = QWidget()
        self.tree = DataBrowserTree()
        self.setCentralWidget(self.tree)
        self.resize(QSize(1340, 1080))
        self.show()


class DataBrowserTree(QTreeView):
    def __init__(self):
        super(DataBrowserTree, self).__init__()

        datafiles_path = r'C:\Repositories\QDscript\DotGUI\TestProjects\Proj_3\datafiles'

        self.model = QFileSystemModel()
        self.model.setRootPath(datafiles_path)
        self.model.setReadOnly(False)
        index = self.model.index(datafiles_path)
        self.setObjectName('dataBrowserTree')

        self.setModel(self.model)
        self.setRootIndex(index)
        self.setAnimated(False)
        self.setIndentation(20)
        self.setSortingEnabled(True)
        self.sortByColumn(0, Qt.AscendingOrder)
        self.setHeaderHidden(True)
        self.setSortingEnabled(False)
        self.setColumnHidden(1, True)
        self.setColumnHidden(2, True)
        self.setColumnHidden(3, True)
        self.setWindowTitle("Dir View")

    def mouseReleaseEvent(self, QMouseEvent):
        if QMouseEvent.button() == 2:
            self.show_rightclick_menu(QMouseEvent.globalPos())

    def show_rightclick_menu(self, pos):
        self.rightclick_menu = QMenu()
        self.action_rename = QAction(self)
        self.action_rename.setText('Rename')
        self.action_rename.triggered.connect(lambda: self.clicked('rename'))
        self.rightclick_menu.addAction(self.action_rename)
        self.rightclick_menu.move(pos.x(), pos.y())
        self.rightclick_menu.show()


    def clicked(self, click_str):
        if click_str == 'rename':
            index = self.selectedIndexes()[0] # This gets the correct QModelIndex
            print(index) # <PyQt5.QtCore.QModelIndex object at 0x1823D930>

    def edit(self, index, trigger, event):
        # When F2 is pressed I get:
        #   index --> QModelIndex object
        #   trigger --> 8 (the key code)
        #   event --> QKeyEvent object

        return QTreeView.edit(self, index, trigger, event)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow(app)
    sys.exit(app.exec_())

You don't have to override the edit() method but use it. On the other hand, instead of overriding the mouseReleaseEvent method that overrides the default behavior, the customContextMenuRequested signal should be used when setting the contextMenuPolicy to Qt::CustomContextMenu as shown below:

class DataBrowserTree(QTreeView):
    def __init__(self):
        super(DataBrowserTree, self).__init__()

        datafiles_path = r'C:\Repositories\QDscript\DotGUI\TestProjects\Proj_3\datafiles'

        self.model = QFileSystemModel()
        self.model.setRootPath(datafiles_path)
        self.model.setReadOnly(False)
        index = self.model.index(datafiles_path)
        self.setObjectName("dataBrowserTree")

        self.setModel(self.model)
        self.setRootIndex(index)
        self.setAnimated(False)
        self.setIndentation(20)
        self.setSortingEnabled(True)
        self.sortByColumn(0, Qt.AscendingOrder)
        self.setHeaderHidden(True)
        self.setSortingEnabled(False)
        for i in (1, 2, 3):
            self.setColumnHidden(i, True)
        self.setWindowTitle("Dir View")

        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_rightclick_menu)

    def show_rightclick_menu(self, pos):
        ix = self.indexAt(pos)

        rightclick_menu = QMenu()
        action_rename = QAction(self)
        action_rename.setText("Rename")
        rightclick_menu.addAction(action_rename)
        action = rightclick_menu.exec_(self.viewport().mapToGlobal(pos))
        if action == action_rename:
            self.edit(ix)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM