2015-08-17 3 views
0

Я хотел бы добавить действие в меню «по умолчанию» контекстуального, который показывается при редактировании текста QStandardItem (в которым показан в QTreeView)PyQt расширить существующие Контекстное меню при редактировании текста QStandardItem (в виде QTreeView)

Это контекстное меню, по-видимому, является контекстным меню по умолчанию виджета QPlainTextEdit. Существуют действия по умолчанию: Отменить, Повторить, Копировать, Вставить, Удалить, Выбрать все. Я хочу добавить пользовательское действие только здесь.

У меня нет информации о том, как изменить это меню.

Заранее благодарен!

ответ

2

Чтобы настроить редактор для QTreeView ячейки вам нужно создать QItemDelegate и связать его с колонкой вашего TreeView.

Пользовательские делегаты могут быть более сложными (например, для изменения сохранения/восстановления поведения редактора), но в этом случае мы просто хотим, чтобы изменить какой класс он использует для создания экземпляра виджета-редактора:

class CustomDelegate(QItemDelegate): 
    def createEditor(self, parent, option, index): 
     editor = CustomLineEdit(parent)     
     return editor 

Это обеспечит, что редактор теперь будет виджет CustomLineEdit, который может иметь любую добавленную функциональность (например, пользовательское контекстное меню). В моем примере ниже я использую слегка измененную версию ответа, предоставленного Achayan, для реализации этого CustomLineEdit.

можно присвоить пользовательский делегат в колонку со следующим кодом (в данном случае я выбрал столбец 0 из TreeView):

# Create custom Delegate which instantiates our custom editor 
delegate = CustomDelegate() 
# Set this delegate for the first column only 
treeview.setItemDelegateForColumn(0, delegate) 

Полный код

import sys 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

class CustomLineEdit(QLineEdit): 
    def __init__(self, *args, **kwargs): 
     super(CustomLineEdit, self).__init__(*args, **kwargs) 
     self.setContextMenuPolicy(Qt.CustomContextMenu) 
     self.customContextMenuRequested.connect(self.__contextMenu) 

    def __contextMenu(self): 
     self._normalMenu = self.createStandardContextMenu() 
     self._addCustomMenuItems(self._normalMenu) 
     self._normalMenu.exec_(QCursor.pos()) 

    def _addCustomMenuItems(self, menu): 
     menu.addSeparator() 
     menu.addAction(u'Test', self.testFunc) 

    def testFunc(self): 
     print "Call" 


class CustomDelegate(QItemDelegate): 
    def createEditor(self, parent, option, index): 
     editor = CustomLineEdit(parent)     
     return editor 


if __name__ == "__main__": 
    app = QApplication(sys.argv) 

    # Create Widgets 
    window = QMainWindow() 
    widget = QWidget() 
    layout = QVBoxLayout(widget) 
    treeview = QTreeView() 
    layout.addWidget(treeview) 
    window.setCentralWidget(widget) 
    window.show() 

    # Create Model 
    model = QStandardItemModel() 
    model.setHorizontalHeaderLabels(['Header 1','Header 2']) 
    treeview.setModel(model) 

    # Create custom Delegate which instantiates our custom editor 
    delegate = CustomDelegate() 
    # Set this delegate for the first column only 
    treeview.setItemDelegateForColumn(0, delegate) 

    # Populate the model with some test data 
    row1 = [] 
    row1.append(QStandardItem("asd")) 
    row1.append(QStandardItem("fgh")) 
    model.appendRow(row1) 
    row2 = [] 
    row2.append(QStandardItem("qwe")) 
    row2.append(QStandardItem("rty")) 
    model.appendRow(row2) 

    app.exec_() 
+0

Большое спасибо за ваш точный и поучительный ответ @three_pineapples! Это именно то, что я искал. Ты мне очень помог сегодня :) Я только что адаптировал ваш код, и это отлично работает. – Glyphosate

+0

@ Glyphosate, если это ответит на ваш вопрос, нажмите на галочку в левой части, чтобы отметить это как принятый ответ. Как только у вас будет достаточная репутация, вы также сможете проголосовать за любые ответы, которые, по вашему мнению, будут полезны. –

+0

Все готово. Большое спасибо. – Glyphosate

1

У меня есть пример для QPlainTextEdit. Вы можете изменить, исходя из ваших потребностей. Надеюсь, что это помогает

class CustomLineEdit(QtGui.QPlainTextEdit): 
    def __init__(self, parent = None): 
     super(CustomLineEdit, self).__init__() 
     self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 
     self.customContextMenuRequested.connect(self.__contextMenu) 

    def __contextMenu(self): 
     self._normalMenu = self.createStandardContextMenu() 
     self._addCustomMenuItems(self._normalMenu) 
     self._normalMenu.exec_(QtGui.QCursor.pos()) 

    def _addCustomMenuItems(self, menu): 
     menu.addSeparator() 
     menu.addAction(u'Test', self.testFunc) 

    def testFunc(self): 
     print "Call" 

class mainwindow(QtGui.QWidget): 
    def __init__(self , parent = None): 
     super(mainwindow, self).__init__()  
     self.setupgui() 
    def setupgui(self): 

     self.resize(800,600) 
     self.setWindowTitle('test') 
     newLayout = QtGui.QHBoxLayout() 
     qlbl = CustomLineEdit() 
     newLayout.addWidget(qlbl) 
     self.setLayout(newLayout) 
     self.show() 


def main(): 

    app = QtGui.QApplication(sys.argv) 
    ex = mainwindow() 
    sys.exit(app.exec_()) 


if __name__ == '__main__': 
    main() 
+0

Почему кто-то проигнорировал это? пожалуйста, скажите мне, что не так с кодом, если вы используете downvote. – Achayan

+0

Если бы мне пришлось угадать, это было бы потому, что это не отвечает на вопрос? OP хочет сделать это при редактировании ячейки в 'QTreeView'. Говорить им «адаптировать этот код» необязательно полезно. –

+0

Кажется довольно простым приспособить код: вам просто нужно подклассифицировать 'QStandardItem' вместо' QPlainTextEdit'. Остальное не меняется, не так ли? Этот ответ мне кажется полезным. – Mel

Смежные вопросы