python - Pyqt - 在“IconMode”中添加到 QTreeViewItem 时,自定义小部件上的选择突出显示丢失
问题描述
我正在尝试创建一个自定义小部件列表,用户单击它们以打开图片/电影。我一切正常,但我失去了通常与项目一起出现的选择突出显示。
我知道它不存在,因为我使用的是自定义小部件。如何在小部件上获得选择突出显示?我希望该项目显示一个透明的蓝色层。
好奇,当我将视图模式更改为 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_())
解决方案
好吧,我找到了一种对我有用的 hacky 方法。我在 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_())
推荐阅读
- javascript - javascript 获取 api 并返回数据以使用它
- autodesk-forge - Autodesk.Viewing.UI.DataTable 中是否存在最佳列表行数?
- ios - 带有baselineOffset的NSAttributedString会导致最后一行被截断
- c++ - 模板模板参数和“<<”运算符(ostream)
- android - 如何防止具有相同重复使用电话号码的两个人共享相同的身份验证帐户?
- node.js - 如何使用 @azure/arm-storage nodejs 将 cors 添加到 Blob 容器
- microsoft-teams - 将应用程序提交从一个目录移动到另一个目录
- sql - oracle中有没有等价于isdate()的函数
- r - 将列添加到分组数据框 dplyr
- c# - 主体不包含“电子邮件地址”的定义