Как правильно упорядочить столбцы в QTreeView на основе списка в качестве входных данных - PullRequest
1 голос
/ 10 июля 2020

Обычно я показываю QTreeView с 20 столбцами. Я хочу, чтобы пользователь переупорядочил столбцы и sh кнопку сохранения, чтобы сохранить порядок в виде списка в ini-файле. При запуске программы я хочу переупорядочить столбцы на основе настроек из ini-файла.

Я сохраняю исходный порядок столбцов в виде списка в «list_origin». Желаемый порядок находится в «list_custom». Например,

list_origin=['From', 'Subject', 'Date']
list_custom=['Date', 'Subject', 'From']

Теперь проблема в том, что когда я перемещаю столбцы с помощью команды moveSection () заголовков модели, исходные индексы иногда больше не верны, потому что столбцы могут быть вставлены между ними и, таким образом, потерять свое происхождение. индекс позиции.

См. пример ниже: нажатие кнопки «Изменить порядок столбцов на дату / тему / от» создаст нежелательный порядок столбцов. Как расположить столбцы в желаемом порядке на основе list_custom?

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# file: treeView_FindCol.py

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def find_col_by_name(tree_obj, col_name: str) -> int:
    """ Returns found column position as integer, else -1 """
    pos_found: int = -1
    model = tree_obj.model()
    if model:
        for col in range(model.columnCount()):
            header = model.headerData(col, Qt.Horizontal, Qt.DisplayRole)
            if str(header) == col_name:
                pos_found = col
    return pos_found
def find_col_by_index(tree_obj, col_index: int) -> int:
    """ Returns found column position as integer, else -1 """
    pos_found: int = -1
    model = tree_obj.model()
    header = tree_obj.header()

    pos_found = header.visualIndex(col_index)
    header_txt = model.headerData(pos_found, Qt.Horizontal, Qt.DisplayRole)

    return pos_found

class App(QWidget):
    FROM, SUBJECT, DATE = range(3)

    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 Treeview Example - pythonspot.com'
        self.left = 800
        self.top = 200
        self.width = 640
        self.height = 240
        self.initUI()

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

        pushButton = QPushButton("Rearrange cols to Date/Subject/From")

        groupBox = QGroupBox("Inbox")
        treeView = QTreeView()
        treeView.setRootIsDecorated(False)
        treeView.setAlternatingRowColors(True)

        pushButton.clicked.connect(lambda: self.rearrange_column_layout(treeView))

        dataLayout = QHBoxLayout()
        dataLayout.addWidget(treeView)
        dataLayout.addWidget(pushButton)

        groupBox.setLayout(dataLayout)

        model = self.createMailModel(self)
        treeView.setModel(model)
        self.addMail(model, 'service@github.com', 'Your Github Donation','03/25/2017 02:05 PM')
        self.addMail(model, 'support@github.com', 'Github Projects','02/02/2017 03:05 PM')
        self.addMail(model, 'service@phone.com', 'Your Phone Bill','01/01/2017 04:05 PM')
        self.addMail(model, 'service@abc.com', 'aaaYour Github Donation','03/25/2017 02:05 PM')
        self.addMail(model, 'support@def.com', 'bbbGithub Projects','02/02/2017 03:05 PM')
        self.addMail(model, 'service@xyz.com', 'cccYour Phone Bill','01/01/2017 04:05 PM')

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

        self.show()

    def createMailModel(self,parent):
        model = QStandardItemModel(0, 3, parent)
        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, mailFrom, subject, date):
        model.insertRow(0)
        model.setData(model.index(0, self.FROM), mailFrom)
        model.setData(model.index(0, self.SUBJECT), subject)
        model.setData(model.index(0, self.DATE), date)

    def rearrange_column_layout(self, treeView):
        print("restore_column_layout() called.")

        list_custom: list = ['Date', 'Subject', 'From']
        list_origin: list = []
        model = treeView.model()
        header = treeView.header()
        col_count = model.columnCount()
        for col_search_index in range(col_count):
            col_found = header.visualIndex(col_search_index)
            header_txt = model.headerData(col_search_index, Qt.Horizontal, Qt.DisplayRole)
            list_origin.append(header_txt)
        print(f"{list_origin=}")
        print(f"{list_custom=}")
        pos_custom: int = 0
        pos_origin_last: int = 0
        for item_custom in list_custom:
            pos_origin: int = 0
            for item_origin in list_origin:
                if item_custom == item_origin:
                    msg_txt = f"moving col '{item_origin}' from {pos_origin} to {pos_custom}."
                    print(msg_txt)
                    QMessageBox.information(self, f"{item_origin}", msg_txt)
                    header.moveSection(pos_origin, pos_custom)
                    pos_origin_last = pos_origin
                pos_origin += 1
            pos_custom += 1


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

Я хочу установить порядок столбцов на основе входного списка

"list_origin" содержит имена заголовков в исходный порядок, например list_origin = ['From', 'Subject', 'Date']

«list_custom» - это желаемый порядок столбцов в моем QTreeView, например list_custom = ['Date', 'Subject' , 'From']

Теперь я перебираю настраиваемый список и хочу разместить столбцы на основе этих позиций с помощью заголовка moveSection ().

Итак, алгоритм в основном таков:

step1: начать с индекса 0 настраиваемого списка, это «Date»

step2: получить позицию «Date» из исходного списка, которая равна 2.

step3: call moveSection (2,0)

Вывод трассировки:

перемещение столбца «Дата» от 2 до 0.

перемещение столбца «Тема» с 1 на 1.

перемещение столбца 'From' от 0 до 2.

Но в любом случае результат будет «From» / «Subject» / «Date» (!), А не как желаемый «Date» / «Su» bject "/" От ".

1 Ответ

0 голосов
/ 10 июля 2020

Лог c предназначен для получения индекса каждого элемента во время итерации, поскольку визуальный порядок меняется в пределах l oop:

def rearrange_column_layout(self, treeView):
    to_list = ["Date", "Subject", "From"]

    header = treeView.header()
    model = treeView.model()
    for i, c in enumerate(to_list[:-1]):
        from_list = [
            model.headerData(header.logicalIndex(visual_index), Qt.Horizontal)
            for visual_index in range(header.count())
        ]
        j = from_list.index(c)
        header.moveSection(j, i)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...