单击QLabel后,将QLabel更改为QStyledItemDelegate中的QCombobox

时间:2020-06-11 11:20:50

标签: pyqt5

我需要将Qlabel中的Qcombobox更改为QStyledItemDelegate。但是,当我单击标签时,组合框出现在QTableView的最后可见行中。 我试图从基础表中获取currentIndex,并通过sender().objectName ()获取点击的来源。两者都是正确的,但是与我如何设置行无关,该组合仍然位于错误的行(最后一个)上。 Solution by CSS中的解决方案不适用于我。

如何将委托中的选定行设置为特定行以替换小部件?

工作示例:

from PyQt5.QtWidgets import QItemDelegate, QLabel, QStyledItemDelegate, QComboBox, QAbstractItemView, QTextEdit, \
    QVBoxLayout, QMainWindow, QWidget, QApplication, QTableView
from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal, QModelIndex, QEvent, QVariant, QAbstractTableModel, QCoreApplication

class ClickLabel(QLabel):
    clicked = pyqtSignal()

    def mousePressEvent(self, event):
        self.clicked.emit()
        QLabel.mousePressEvent(self, event)

class dateDelegate2(QStyledItemDelegate):
    def __init__(self, parent):
        super (dateDelegate2, self).__init__ (parent)

    def paint(self, painter, option, index):
        if (
            isinstance(self.parent(), QAbstractItemView)
            and self.parent().model() is index.model()
        ):
            self.parent().openPersistentEditor(index)

    def createEditor(self, parent, option, index):
        editor = QLabel(parent)

        self.dateValue = QLabel()
        self.dateValue.setFixedHeight(160)
        self.dateValue.setAlignment(Qt.AlignTop)
        self.dateValue.setEnabled(False)
        self.dateValue.setStyleSheet ("QTextEdit{ border-width: 0px; border-style: solid; border-color: gray; color: blue; font-size: 12px }");

        self.itemValue = ClickLabel()
        self.itemValue.setFixedHeight(200)
        self.itemValue.setStyleSheet ("QLabel{ border-width: 0px; border-style: solid; border-color: gray; color: blue; font: bold; font-size: 14px  }");
        self.itemValue.setAlignment(Qt.AlignTop)
        self.itemValue.setObjectName('itemValue_' + str(index.row()))
        self.itemValue.clicked.connect (lambda: self.directClick(index))

        self.mainlayout = QVBoxLayout ()
        self.mainlayout.addWidget(self.itemValue)
        self.mainlayout.addWidget (self.dateValue)
        editor.setLayout(self.mainlayout)
        return editor

    def setEditorData(self, editor, index):
        dateString = str(index.data())
        self.dateValue.setText(dateString)
        self.itemValue.setText('itemValue_' + str(index.row()))

    def setModelData(self, editor, model, index, rps_id):
        pass

    def inputComboChanged(self):
        print("inputComboChanged:", self.inputCombo.currentIndex(), self.inputCombo.currentText())

    def directClick(self, index):
        fromObject = self.sender().objectName ()
        fromRow = fromObject.split('_')[1]
        print("directClick !!!", fromObject, fromRow)
        delegateindex = self.parent().model().index(int(fromRow),0)
        print("dindex:",delegateindex.row())

        # Does not set to position
        self.parent().setCurrentIndex (delegateindex)
        # Does not help
        self.parent().scrollTo (delegateindex)

        self.inputCombo = QComboBox ()
        self.inputCombo.addItems(['A1','A2','A3'])
        self.inputCombo.setEditable (True)
        self.inputCombo.currentIndexChanged.connect (self.inputComboChanged)
        self.mainlayout.removeWidget (self.itemValue)
        self.mainlayout.insertWidget (0, self.inputCombo, alignment=Qt.AlignTop)

class Model(QAbstractTableModel):
    ActiveRole = Qt.UserRole + 1
    def __init__(self, datain, headerdata, parent=None):
        super().__init__()
        self.arraydata = datain
        self.headerdata = headerdata

    def headerData(self, section, orientation, role):
        if role == Qt.DisplayRole and orientation == Qt.Horizontal:
            return QVariant(self.headerdata[section])
        return QVariant()

    def rowCount(self, parent=QModelIndex()):
        if parent.isValid(): return 0
        return len(self.arraydata)

    def columnCount(self, parent=QModelIndex()):
        if parent.isValid(): return 0
        if len(self.arraydata) > 0:
            return len(self.arraydata[0])
        return 0

    def flags(self, index):
        return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable

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

    def print_arraydata(self):
        print(self.arraydata)

    def insert_row(self, data, position, rows=1):
        self.beginInsertRows(QModelIndex(), position, position + rows - 1)
        for i, e in enumerate(data):
            self.arraydata.insert(i+position, e[:])
        self.endInsertRows()
        return True

    def remove_row(self, position, rows=1):
        self.beginRemoveRows(QModelIndex(), position, position + rows - 1)
        self.arraydata = self.arraydata[:position] + self.arraydata[position + rows:]
        self.endRemoveRows()
        return True

    def append_row(self, data):
        self.insert_row([data], self.rowCount())

class Main(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # create table view:
        self.tableview = self.createTable()
        # create layout
        layout = QVBoxLayout()
        layout.addWidget(self.tableview)
        # initializing layout
        self.setGeometry(0, 0, 500, 500)
        self.centralwidget = QWidget()
        self.centralwidget.setLayout(layout)
        self.setCentralWidget(self.centralwidget)

    def createTable(self):
        tv = QTableView()
        tv.resizeRowsToContents()
        # set header for columns:
        header = ['Name', 'Type', 'var1', 'var2', 'var3']
        tabledata = [[1,2,3,4],[11,12,13,14],[21,22,23,24],[31,32,33,34]]
        tablemodel = Model(tabledata, header, self)
        tv.setModel (tablemodel)
        for row in range (tablemodel.rowCount ()):
            tv.setRowHeight(row, 200)
        tv.setItemDelegateForColumn(1, dateDelegate2(tv))
        return tv

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    main = Main()
    main.show()
    sys.exit(app.exec_())

0 个答案:

没有答案