Форум сайта python.su
Есть модель QStandardItemModel, данные из которой оторажаются при помощи QTableView. Необходимо сделать так, чтобы при редактировании последнего столбца таблицы использовался нестандартный элемент, а именно, поле ввода с кнопкой открытия диалога выбора папки (QFileDialog.getExistingDirectory()). Т.е. надо создать делегат и повесить его на нужный столбец QTableView.
Вот на создании делегата я и застрял: не могу понять как сделать передачу значения в делегат и из него. Код такой
class DirectoryDelegate( QItemDelegate ): selectClicked = pyqtSignal() def __init__( self, parent = None ): QItemDelegate.__init__( self, parent ) def createEditor( self, parent, options, index ): self.btnSelect = QPushButton( self.tr( "..." ) ) self.lineEdit = QLineEdit() hbl = QHBoxLayout() hbl.addWidget( self.lineEdit ) hbl.addWidget( self.btnSelect ) self.btnSelect.clicked.connect( self.selectDirectory ) myWidget = QWidget( parent ) myWidget.setBackgroundRole( QPalette.Window ) myWidget.setAutoFillBackground( True ) myWidget.setLayout( hbl ) return myWidget def setEditorData( self, editor, index ): value = index.model().data( index, Qt.EditRole ).toString() editor.setText( value ) def setModelData( self, editor, model, index ): model.setData( index, editor.text(), Qt.EditRole ) def selectDirectory( self ): dirName = QFileDialog.getExistingDirectory( None, self.tr( "Select directory" ), "", QFileDialog.ShowDirsOnly ) if dirName.isEmpty(): return self.lineEdit.setText( dirName )
editor.setText( value )
editor.findChild( QLineEdit, "lineEdit" )
Офлайн
Вам нужно сделать свой виджет - editor, в котором будут все элементы (кнопки, lineEdit-ы), сигналы и функции.
Псевдокод:
class DirChooseEditor(QtGui.QWidget): def __init__(self, parent=None): super(DirChooseEditor, self).__init__(parent) self.lineEdit = ... self.button = ... # layout, style, signals etc # ... def _on_button_clicked(self): # show select dir dialog # update lineedit def get_directory(self): return self.lineEdit.text() def set_directory(self, directory): self.lineEdit.setText(directory) class DirectoryDelegate(QItemDelegate): # ... def createEditor( self, parent, options, index ): return DirChooseEitor(parent) # maybe set initial directory before return, etc def setEditorData( self, editor, index ): value = ... editor.set_directory(value) # ...
Отредактировано reclosedev (Июнь 14, 2012 08:02:34)
Офлайн
Спасибо, часть вопросов снялась, но возникли другие. Сделал виджет по вашему совету
from PyQt4.QtCore import * from PyQt4.QtGui import * from ui_directoryselectorbase import Ui_DirectorySelector class DirectorySelector( QWidget, Ui_DirectorySelector ): def __init__( self, parent = None ): QWidget.__init__( self, parent ) self.setupUi( self ) self.setFocusPolicy( Qt.StrongFocus ) self.btnSelect.clicked.connect( self.selectDirectory ) def selectDirectory( self ): dirName = QFileDialog.getExistingDirectory( None, self.tr( "Select directory" ), "", QFileDialog.ShowDirsOnly ) if dirName.isEmpty(): return self.lineEdit.setText( dirName ) def text( self ): return self.lineEdit.text() def setText( self, value ): self.lineEdit.setText( value )
from PyQt4.QtCore import * from PyQt4.QtGui import * import directoryselector class DirectoryDelegate( QItemDelegate ): def __init__( self, parent = None ): QItemDelegate.__init__( self, parent ) def createEditor( self, parent, options, index ): return directoryselector.DirectorySelector( parent ) def setEditorData( self, editor, index ): value = index.model().data( index, Qt.EditRole ).toString() editor.setText( value ) def setModelData( self, editor, model, index ): model.setData( index, editor.text(), Qt.EditRole )
File “directoryselector.py”, line 56, in selectDirectory
self.lineEdit.setText( dirName )
RuntimeError: underlying C/C++ object has been deleted
Офлайн
В коде выглядит все нормально, но вот что нагуглил:
http://stackoverflow.com/questions/2468587/c-object-destroyed-in-qcombobox-descendant-editor-in-delegate
Получается, что т.к. вызывается модальный диалог для выбора папки, фокус у editor'а пропадает и виджет удаляется. Странно это конечно.
Офлайн
Огромное спасибо! Помогло
Офлайн