Как заставить QTableView входить в режим редактирования только по двойному щелчку

Установка флага Qt.ItemIsEnabled делает QTableView элементы доступными для редактирования. Чтобы войти в режим редактирования элемента, пользователь может просто дважды щелкнуть по нему. Другой способ отредактировать элемент - выбрать его и нажать клавишу на клавиатуре. Как отключить второй способ входа в режим редактирования элемента?

Вот изображение, показывающее QTableView с выбранным элементом:

введите описание изображения здесь

Как только пользователь нажимает клавишу на клавиатуре, выбранный элемент уже находится в режиме редактирования:

введите описание изображения здесь

Такое поведение QTableView по умолчанию делает невозможным определение ярлыков функций, так как вместо запуска функции привязки к ярлыку элемент QListView переходит в режим редактирования .... Как заставить QTableView переходить в режим редактирования только по двойному щелчку?

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

class Model(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = ['Item_A_001','Item_A_002','Item_B_001','Item_B_002']

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)       
    def columnCount(self, parent=QModelIndex()):
        return 1

    def data(self, index, role):
        if not index.isValid(): return QVariant()
        elif role != Qt.DisplayRole:
            return QVariant()

        row=index.row()
        if row<len(self.items):
            return QVariant(self.items[row])
        else:
            return QVariant()
    def flags(self, index):
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable

class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        tableModel=Model(self)               

        self.view=QTableView(self) 
        self.view.setModel(tableModel)
        self.view.horizontalHeader().setResizeMode(QHeaderView.Stretch)

        layout = QVBoxLayout(self)
        layout.addWidget(self.view)
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

person alphanumeric    schedule 28.01.2015    source источник


Ответы (2)


вам нужно повторно реализовать обработчик четности keyPressEvent в вашем QTableView. Для этого вы можете создать собственный класс QTableView и заново реализовать внутри него обработчик событий.

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

#Your new customized QTableView
class CustomQTableView(QTableView):    
    def __init__(self, *args, **kwargs):
        QTableView.__init__(self, *args, **kwargs) #Use QTableView constructor

    def keyPressEvent(self, event): #Reimplement the event here, in your case, do nothing
        return

class Model(QAbstractTableModel):
    def __init__(self, parent=None, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.items = ['Item_A_001','Item_A_002','Item_B_001','Item_B_002']

    def rowCount(self, parent=QModelIndex()):
        return len(self.items)       
    def columnCount(self, parent=QModelIndex()):
        return 1

    def data(self, index, role):
        if not index.isValid(): return QVariant()
        elif role != Qt.DisplayRole:
            return QVariant()

        row=index.row()
        if row<len(self.items):
            return QVariant(self.items[row])
        else:
            return QVariant()
    def flags(self, index):
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable


class MyWindow(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        print "c"
        tableModel=Model(self)               

        self.view=CustomQTableView(self) #Call your custom QTableView here
        self.view.setModel(tableModel)
        self.view.horizontalHeader().setResizeMode(QHeaderView.Stretch)

        layout = QVBoxLayout(self)
        layout.addWidget(self.view)
        self.setLayout(layout)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

Таким образом, keyPressEvent перезаписывается, и ничего не происходит, но ваше событие двойного щелчка остается прежним.

person DrHaze    schedule 28.01.2015
comment
Спасибо DrHaze за простое решение! - person alphanumeric; 28.01.2015

Я думаю, что лучшим решением будет установка триггеров редактирования, которые вы хотите. Поскольку QTableView наследуется от QAbstractItemView, вы можете использовать void setEditTriggers (EditTriggers триггеры). Итак, код вашего пользовательского QTableView будет таким:

from PyQt4.QtGui import QAbstractItemView, QTableView

class CustomQTableView(QTableView):    
    def __init__(self, *args):
        super().__init__(*args)
        self.setEditTriggers(QAbstractItemView.NoEditTriggers |
                             QAbstractItemView.DoubleClicked)
person Andres Espinosa    schedule 01.12.2015