Pyqt - Потеря выделения выделения на пользовательском виджете при добавлении в QTreeViewItem в «IconMode» - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь создать список пользовательских виджетов, в которых пользователь щелкает их, чтобы открывать картинки / фильмы. У меня все работает, но я потерял выделение выделения, которое обычно идет с элементом.

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

Любопытно, когда я меняю режим просмотра на ListMode, вы можете видеть выделение синего цвета. Я прокомментировал это в примере кода.

Он пример с полосатой спиной и полосатой спиной, так как я все равно могу его получить. Переключите представления списка и выберите элемент, чтобы увидеть другое поведение.

import sys
from datetime import datetime
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui


class EntryWidget(QtWidgets.QWidget):

    def __init__(self):
        super(EntryWidget, self).__init__()
        self.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))

        # controls
        self.thumbnail = QtWidgets.QLabel()
        self.version = QtWidgets.QLabel()
        self.date = QtWidgets.QLabel()
        self.name = QtWidgets.QLabel()
        self.name.setAlignment(QtCore.Qt.AlignCenter)
        self.author = QtWidgets.QLabel()
        self.author.setAlignment(QtCore.Qt.AlignRight)
        self.dummy = QtWidgets.QLabel(" ")

        # layout
        main_layout = QtWidgets.QVBoxLayout()

        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)
        main_layout.addWidget(self.name)
        main_layout.addWidget(self.thumbnail)
        main_layout.addWidget(self.version)
        main_layout.addWidget(self.date)
        main_layout.addWidget(self.author)
        main_layout.addWidget(self.dummy)
        main_layout.addStretch()

        self.setLayout(main_layout)

    def set_size(self, w, h):
        self.thumbnail.setFixedSize(w, h)

    def set_version(self, name):
        self.version.setText(" Version:" + str(name))

    def set_date(self, name):
        date_string = " Date: {0}/{1}/{2}\n Time: {3}:{4}:{5}".format(
            str(name.day).zfill(2),
            str(name.month).zfill(2),
            name.year,
            name.hour,
            name.minute,
            name.second)
        self.date.setText(date_string)

    def set_name(self, name):
        self.name.setText(name)

    def set_author(self, name):
        self.author.setText(name + " ")

class QuickExample(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(QuickExample, self).__init__(parent)
        self.resize(500, 500)
        layout = QtWidgets.QVBoxLayout()

        media_list = QtWidgets.QListWidget(self)

        # switch the views and select an item
        media_list.setViewMode(QtWidgets.QListWidget.IconMode)
        # media_list.setViewMode(QtWidgets.QListWidget.ListMode)

        media_list.setResizeMode(QtWidgets.QListWidget.Adjust)
        media_list.setMovement(QtWidgets.QListWidget.Static)
        media_list.setSpacing(5)

        # dummy media, usually sourced from database
        media = [
            {"version": 1, "date": datetime.now(), "name": "Entry 01", "author": "Bob"},
            {"version": 2, "date": datetime.now(), "name": "Entry 02", "author": "John"}
        ]

        for i in media:
            # Create media Entry
            entry = EntryWidget()
            entry.set_version(i["version"])
            entry.set_date(i["date"])
            entry.set_size(128, 72)
            entry.set_name(i["name"])
            entry.set_author(i["author"])

            # Create QListWidgetItem
            media_item = QtWidgets.QListWidgetItem(media_list)

            # Set size hint
            media_item.setSizeHint(entry.sizeHint())

            # Add QListWidgetItem into QListWidget
            media_list.addItem(media_item)
            media_list.setItemWidget(media_item, entry)

        layout.addWidget(media_list)
        self.setLayout(layout)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    example = QuickExample()
    example.show()
    sys.exit(app.exec_())

1 Ответ

0 голосов
/ 13 апреля 2020

Ну, я нашел хакерский способ сделать это, который работает для меня. Я добавил пустой текст в QListWidgetItem и сделал шрифт очень большим. Это вернуло подсветку для элемента.

media_item.setText("  ") # set the item with a  dummy string
media_item.setFont(QFont('Verdana', 180)) # make the font big so it covers the whole widget

После некоторых исследований я обнаружил, что использование QListView и QItemDelegate является способом сделать это. Я не смог найти хороший пример / учебник, использующий PyQt5, поэтому я просто покажу его.

Вот код

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

from sys      import exit     as sysExit
from datetime import datetime as dtDateTime

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

        self.setCursor(QCursor(Qt.PointingHandCursor))
        self.setFocusPolicy(Qt.StrongFocus)  # Sets the Highlight when it has focus

      # Controls
        self.thumbnail = QLabel()
        self.version = QLabel()
        self.date = QLabel()
        self.name = QLabel()
        self.name.setAlignment(Qt.AlignCenter)
        self.author = QLabel()
        self.author.setAlignment(Qt.AlignRight)
        self.dummy = QLabel(" ")

      # Layout Container
        VBox = QVBoxLayout()
        VBox.setContentsMargins(0, 0, 0, 0)
        VBox.setSpacing(0)
        VBox.addWidget(self.name)
        VBox.addWidget(self.thumbnail)
        VBox.addWidget(self.version)
        VBox.addWidget(self.date)
        VBox.addWidget(self.author)
        VBox.addWidget(self.dummy)
        VBox.addStretch()

        self.setLayout(VBox)

    def set_size(self, w, h):
        self.thumbnail.setFixedSize(w, h)

    def set_version(self, name):
        self.version.setText(" Version:" + str(name))

    def set_date(self, name):
        date_string = " Date: {0}/{1}/{2}\n Time: {3}:{4}:{5}".format(
            str(name.day).zfill(2),
            str(name.month).zfill(2),
            name.year,
            name.hour,
            name.minute,
            name.second)
        self.date.setText(date_string)

    def set_name(self, name):
        self.name.setText(name)

    def set_author(self, name):
        self.author.setText(name + " ")

class QuickExample(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.resize(500, 500)

        media_list = QListWidget(self)

        # switch the views and select an item
        media_list.setViewMode(QListWidget.IconMode)

        media_list.setResizeMode(QListWidget.Adjust)
        media_list.setMovement(QListWidget.Static)
        media_list.setSpacing(5)

        # dummy media, usually sourced from database
        media = [
            {"version": 1, "date": dtDateTime.now(), "name": "Entry 01", "author": "Bob"},
            {"version": 2, "date": dtDateTime.now(), "name": "Entry 02", "author": "John"}
        ]

        for i in media:
            # Create media Entry
            entry = EntryWidget()
            entry.set_version(i["version"])
            entry.set_date(i["date"])
            entry.set_size(128, 72)
            entry.set_name(i["name"])
            entry.set_author(i["author"])

            # Create QListWidgetItem
            media_item = QListWidgetItem(media_list)

            ###########
            # the fix #
            ###########

            media_item.setText("  ") # set the item with a dummy string
            media_item.setFont(QFont('Verdana', 180)) # make the font big so it covers the whole widget

            # Set size hint
            media_item.setSizeHint(entry.sizeHint())

            # Add QListWidgetItem into QListWidget
            media_list.addItem(media_item)
            media_list.setItemWidget(media_item, entry)

        VBox = QVBoxLayout()
        VBox.addWidget(media_list)

        self.setLayout(VBox)


if __name__ == "__main__":
    MainEventHandler = QApplication([])
    MainApplication = QuickExample()
    MainApplication.show()
    sysExit(MainEventHandler.exec_())
...