хранить и извлекать данные об элементах / строках в QTreeView () - Object через QStardItemModel ()

Я заполняю данные из базы данных SQLite в элемент управления PyQt5 TreeView (QTreeView). Данные записываются через QStandardItemModel ().

Проблема: я хочу запомнить row_id для каждой строки, не отображая его. Раньше я выбирал его в запросе, но скрывал столбец. Но при запросе row_id из столбца с index = 0 это не удается, потому что он не отображается.

Я не знаю а.) Как сохранить row_id, чтобы б.) Получить его позже. Я хочу перебрать выбранные строки и выполнить некоторые действия с соответствующими row_id (например, массовое удаление, массовое редактирование, массовое копирование и т. Д.)

model.setData всегда нужен индекс-столбец ... Qt.UserRole, похоже, не удается получить данные.

Код:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class App(QWidget):
    MAIL_RANGE = 4
    ID, FROM, SUBJECT, DATE = range(MAIL_RANGE)

    def __init__(self):
        super().__init__()      
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 240
        self.initUI()

        self.dataView.setSelectionMode(QAbstractItemView.ExtendedSelection)  #  <- enable selection of rows in tree
        self.dataView.setEditTriggers(QAbstractItemView.NoEditTriggers)      #  <- disable editing items in tree

        for i in range(0, 2):
            self.dataView.resizeColumnToContents(i)

        self.pbOk = QPushButton(self)
        self.pbOk.setText("Ok")
        self.pbOk.move(400,0)
        self.pbOk.show()

        # connect handlers
        self.dataView.doubleClicked.connect(self.on_dataView_doubleClicked)
        self.pbOk.clicked.connect(self.on_pbOk_clicked)

    def on_dataView_doubleClicked(self):
        print("on_dataView_doubleClicked() called.")

    def on_pbOk_clicked(self):
        print("on_pbOk_clicked() called.")

        # get all IDs
        message: str = ""
        col_ind: int = 0
        for item in self.dataView.selectedIndexes():
            if col_ind % (self.MAIL_RANGE) == 0:  # indicates a row beginning
                text = item.data(Qt.DisplayRole)  # or ix.data()
                message = message + "\n" + str(text)
                self.create_dialog(text)
            col_ind += 1
        print(message)

    def create_dialog(self, id):
        print("dialog called for " + str(id))
        myDlg = QDialog(self)
        lbl = QLabel(myDlg)
        lbl.setText("Hello id: " + str(id))        
        myDlg.show()
        myDlg.resize(300,200)

    def initUI(self):        
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.dataGroupBox = QGroupBox("Inbox")
        self.dataView = QTreeView()
        self.dataView.setRootIsDecorated(False)
        self.dataView.setAlternatingRowColors(True)        

        dataLayout = QHBoxLayout()
        dataLayout.addWidget(self.dataView)
        self.dataGroupBox.setLayout(dataLayout)

        model = self.createMailModel(self)
        self.dataView.setModel(model)
        self.addMail(model, 1, '[email protected]', 'Your Github Donation','03/25/2017 02:05 PM')
        self.addMail(model, 2, '[email protected]', 'Github Projects','02/02/2017 03:05 PM')
        self.addMail(model, 3, '[email protected]', 'Your Phone Bill','01/01/2017 04:05 PM')
        self.addMail(model, 4, '[email protected]', 'aaaYour Github Donation','03/25/2017 02:05 PM')
        self.addMail(model, 5, '[email protected]', 'bbbGithub Projects','02/02/2017 03:05 PM')
        self.addMail(model, 6, '[email protected]', 'cccYour Phone Bill','01/01/2017 04:05 PM')

        self.dataView.setColumnHidden(0, True)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.dataGroupBox)
        self.setLayout(mainLayout)

        self.show()

    def createMailModel(self,parent):
        model = QStandardItemModel(0, self.MAIL_RANGE, parent)
        model.setHeaderData(self.ID, Qt.Horizontal, "ID")
        model.setHeaderData(self.FROM, Qt.Horizontal, "From")
        model.setHeaderData(self.SUBJECT, Qt.Horizontal, "Subject")
        model.setHeaderData(self.DATE, Qt.Horizontal, "Date")
        return model

    def addMail(self, model, mailID, mailFrom, subject, date):
        model.insertRow(0)
        model.setData(model.index(0, self.ID), mailID)
        model.setData(model.index(0, self.FROM), mailFrom)
        model.setData(model.index(0, self.SUBJECT), subject)
        model.setData(model.index(0, self.DATE), date)        

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Заворачивать:

1.) В addMail () я хотел бы добавить идентификатор во вставленную строку.

2.) В событии on_pbOk_clicked () я хочу перебрать выбранные строки и получить все идентификаторы для соответствующей строки.

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


person ProfP30    schedule 18.03.2019    source источник


Ответы (1)


Поскольку вы установили, что выбор осуществляется по строкам, необходимо только получить строку и выполнить итерацию по ней, в этом случае с помощью set получить выбранные строки и itero по столбцам.

def on_pbOk_clicked(self):
    message: str = ""
    rows = set(ix.row() for ix in self.dataView.selectedIndexes())
    for row in rows:
        values_for_row = []
        for col in range(App.MAIL_RANGE):
            it = self.dataView.model().item(row, col)
            values_for_row.append(it.text())
        text = " ".join(values_for_row)
        self.create_dialog(text)
        message += "\n" + text
    print(message)
person eyllanesc    schedule 18.03.2019
comment
Это ... просто идеально! Большое спасибо! - person ProfP30; 19.03.2019
comment
возможно, у вас тоже есть идея ... stackoverflow.com/questions/55354274/ - person ProfP30; 27.03.2019