Подсказка PyQt для QTreeView

Пожалуйста, объясните, как включить и показать всплывающую подсказку для каждого элемента в QTreeView. Я нашел образец кода class TreeModel(QAbstractItemModel), но из-за моего начального уровня я не могу понять, как применить его для своих нужд.

Данные для всплывающей подсказки должны быть взяты из значения ключа "note" в словаре data_for_tree.

#!/usr/bin/env python -tt
# -*- coding: utf-8 -*-

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

import sys
reload(sys)
sys.setdefaultencoding('utf8')

data_for_tree = {"tomato":{"color":"red","ammount":"10", "note":"a note for tomato"},"banana":{"color":"yellow","ammount":"1", "note":"b note for banana"}, "some fruit":{"color":"unknown","ammount":"100", "note":"some text"}}

class TreeModel(QAbstractItemModel):

    def data(self, index, role=Qt.DisplayRole):
        #...
        if role == Qt.ToolTipRole:
            return 'ToolTip'

    def flags(self, index):
        if not index.isValid():
            return Qt.NoItemFlags # 0
        return Qt.ItemIsSelectable # or Qt.ItemIsEnabled            

class ProxyModel(QSortFilterProxyModel):

    def __init__(self, parent=None):
        super(ProxyModel, self).__init__(parent)

    def lessThan(self, left, right):
        leftData = self.sourceModel().data(left)
        rightData = self.sourceModel().data(right)
        try:
            return float(leftData) < float(rightData)
        except ValueError:
            return leftData < rightData

class MainFrame(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.MyTreeView = QTreeView()
        self.MyTreeViewModel = QStandardItemModel()
        self.MyTreeView.setModel(self.MyTreeViewModel)
        self.most_used_cat_header = ['Name', "ammount", "color"]
        self.MyTreeViewModel.setHorizontalHeaderLabels(self.most_used_cat_header)
        self.MyTreeView.setSortingEnabled(True)
        self.MyTreeView_Fill()

        MainWindow = QHBoxLayout(self)    
        MainWindow.addWidget(self.MyTreeView)
        self.setLayout(MainWindow)

    def MyTreeView_Fill(self):
        for k in data_for_tree:
            name = QStandardItem(k)
            ammount = QStandardItem(data_for_tree[k]["ammount"])
            note = QStandardItem(data_for_tree[k]["color"])
            tooltip = data_for_tree[k]["note"]
            item = (name, ammount, note)
            self.MyTreeViewModel.appendRow(item)
        self.MyTreeView.sortByColumn(1, Qt.DescendingOrder)
        proxyModel = ProxyModel(self)
        proxyModel.setSourceModel(self.MyTreeViewModel)
        self.MyTreeView.setModel(proxyModel)

        c = 0
        while c < len(self.most_used_cat_header):
            self.MyTreeView.resizeColumnToContents(c)
            c=c+1

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainFrame()
    main.show()
    main.move(app.desktop().screen().rect().center() - main.rect().center())
sys.exit(app.exec_())

person Sergii Artele    schedule 02.06.2015    source источник


Ответы (1)


Поскольку вы используете классы QStandardItem и QStandardItemModel (что я бы и рекомендовал!), вам не нужно возиться с классом TreeModel, который вы нашли. Создание собственной модели требуется редко, но по какой-то причине учебные пособия часто рекомендуют вам это сделать. Если вы обнаружите что-то, побуждающее вас создать подкласс QAbstractItemModel, я предлагаю вам сначала проверить переполнение стека, чтобы увидеть, есть ли более простой способ сделать это! В этом случае есть очень простой способ добавить свои всплывающие подсказки.

Если вы посмотрите на документацию C++ (которую я часто нахожу более полезной, чем документация PyQt для выяснения доступных методов), вы увидите, что QStandardItem имеет метод с именем setToolTip().

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

name = QStandardItem(k)
ammount = QStandardItem(data_for_tree[k]["ammount"])
note = QStandardItem(data_for_tree[k]["color"])
tooltip = data_for_tree[k]["note"]
name.setToolTip(tooltip)
ammount.setToolTip(tooltip)
note.setToolTip(tooltip)

Здесь я установил одинаковую всплывающую подсказку для каждой ячейки в строке (имя, сумма и примечание), но вы можете легко изменить это, чтобы иметь другую всплывающую подсказку для одной из ячеек (надеюсь, это очевидно, как это сделать)

person three_pineapples    schedule 03.06.2015
comment
Спасибо. Конечно, я искал решение в stackoverflow и нашел метод setTooltip, но причина, по которой я задал вопрос, заключается в том, что я пытался применить этот метод к item. В моем случае item - это кортеж, поэтому было сообщение об ошибке. Спасибо за объяснение. - person Sergii Artele; 03.06.2015
comment
@SergiiArtele А, вижу! Что ж, рад, что смог помочь! - person three_pineapples; 03.06.2015