I am trying to create a list of custom widgets where a user clicks them to open pictures/movies. I have everything working but I have lost the selection highlighting that usually comes with an item.
I know it's not there because I'm using a custom widget. How do I get selection highlight on the widget? I would like the item to show a transparent layer of blue.
Curious, when I change the view mode to ListMode you can see the blue selection. I have commented it out in the example code.
He is a striped back example, well as striped back as I can get it anyway. Switch the list views and select an item to see the different behaviour.
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_())
Well, I have found a hacky way of doing this which works fo me. I added some blank text to the QListWidgetItem and made the font really big. This brought back the highlighting for the item.
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
After some research I found that using QListView and QItemDelegate is way to do this. I couldn't find a good example/tutorial using PyQt5 so I will just use this for now.
Here is the code
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_())