[英]How to change background color of selected or clicked cell in a pyqt5 QTableWidget?
[英]Background color of the particular cell is not changing after clicking specific cells in qTableWidget pyqt5
所以我有一個 1 行多列的表格,我使用自定義委托 function 作為圖像縮略圖。 當我單擊它時,我還包括了設置的背景顏色 function。 但是,它不會更改項目背景的顏色。 我必須使用自定義委托 function 以便我的圖標圖像從不同的單元格相互粘貼,而沒有任何額外的空格。
我的代碼如下
import random
from PyQt5 import QtCore, QtGui, QtWidgets
imagePath2 = "arrowREDHead.png"
imagePath = "arrowREDBody.png"
class IconDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter, option, index):
icon = index.data(QtCore.Qt.DecorationRole)
mode = QtGui.QIcon.Normal
if not (option.state & QtWidgets.QStyle.State_Enabled):
mode = QtGui.QIcon.Disabled
elif option.state & QtWidgets.QStyle.State_Selected:
mode = QtGui.QIcon.Selected
state = (
QtGui.QIcon.On
if option.state & QtWidgets.QStyle.State_Open
else QtGui.QIcon.Off
)
pixmap = icon.pixmap(option.rect.size(), mode, state)
painter.drawPixmap(option.rect, pixmap)
def sizeHint(self, option, index):
return QtCore.QSize(20, 20)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
table = QtWidgets.QTableWidget(1, 10)
delegate = IconDelegate(table)
table.setItemDelegate(delegate)
self.setCentralWidget(table)
for j in range(table.columnCount()):
if(j % 2 == 0):
pixmap = QtGui.QPixmap(imagePath)
icon = QtGui.QIcon(pixmap)
it = QtWidgets.QTableWidgetItem()
it.setIcon(icon)
table.setItem(0, j, it)
else:
pixmap = QtGui.QPixmap(imagePath2)
icon = QtGui.QIcon(pixmap)
it = QtWidgets.QTableWidgetItem()
it.setIcon(icon)
table.setItem(0, j, it)
table.item(0, 1).setBackground(QtGui.QColor(100,100,150))
table.resizeRowsToContents()
table.resizeColumnsToContents()
table.setShowGrid(False)
table.itemClicked.connect(self.sequenceClicked)
def sequenceClicked(self, item):
self.itemClicked = item
print("item", item)
item.setBackground(QtGui.QColor(255, 215, 0))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
這是圖標之間有間隙的圖像,它形成的不是一個完美的箭頭,這就是為什么我使用自定義委托 function 將圖標粘在一起,讓它看起來像一個完美的箭頭
這是具有完美箭頭外觀的圖像,因為使用委托 function 在單元格之間沒有任何間隙。 但是,它不允許我更改單元格的背景顏色。
這是箭頭的圖像
這是箭頭體的圖像
與任何重寫的 function 一樣,如果未調用基本實現,則忽略默認行為。
paint()
是 function 負責繪制項目的任何方面,包括其背景。 由於在您的覆蓋中您只是在繪制像素圖,因此缺少其他所有內容,因此解決方案是調用基本實現然后繪制像素圖。
但是,在這種特定情況下,這不是正確的選擇,因為基本實現已經繪制了項目的裝飾,並且在某些條件下(假設像素圖具有 alpha 通道),它可能會導致圖像重疊.
有三種可能的解決方案。
在這種情況下,我們執行基本實現的操作,即使用 CE_ItemViewItem 調用樣式drawControl
CE_ItemViewItem
,但我們在此之前修改選項,刪除與圖標相關的任何內容:
def paint(self, painter, option, index):
# create a new option (as the existing one should not be modified)
# and initialize it for the current index
option = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(option, index)
# remove anything related to the icon
option.features &= ~option.HasDecoration
option.decorationSize = QtCore.QSize()
option.icon = QtGui.QIcon()
if option.widget:
style = option.widget.style()
else:
style = QtWidgets.QApplication.style()
# call the drawing function for view items
style.drawControl(style.CE_ItemViewItem, option, painter, option.widget)
# proceed with the custom drawing of the pixmap
icon = index.data(QtCore.Qt.DecorationRole)
# ...
QStyledItemDelegate 總是在其大多數函數的開頭調用initStyleOption
,包括paint
和sizeHint
。 通過覆蓋 function,我們可以更改繪圖的某些方面,包括圖標 alignment 和定位。
在這種特定情況下,知道我們只有兩種類型的圖標,並且它們必須根據圖像右對齊或左對齊,因此更新適當的裝飾尺寸(基於圖標的最佳尺寸)就足夠了,然后alignment 基於列。
class IconDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super().initStyleOption(option, index)
option.decorationSize = option.icon.actualSize(option.rect.size())
if index.column() & 1:
option.decorationPosition = option.Left
option.decorationAlignment = QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter
else:
option.decorationPosition = option.Right
option.decorationAlignment = QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter
注意:此方法僅適用於圖像都具有相同比例且未手動更改行高的情況。
Qt 使用角色來存儲和檢索每個索引的各個方面(字體、背景等),並且可以定義用戶角色來存儲自定義數據。
setIcon()
實際上使用DecorationRole
在項目中設置一個QIcon,並且委托使用它來繪制它。 如果為該角色返回的數據為空/無效,則不會繪制任何圖標。
如果我們不使用setIcon()
而是將圖標存儲在具有自定義角色的項目中,默認的繪圖函數顯然不會繪制任何裝飾,但我們仍然可以從委托中訪問它。
# we usually define roles right after the imports, as they're constants
ImageRole = QtCore.Qt.UserRole + 1
class IconDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter, option, index):
super().paint(painter, option, index)
icon = index.data(ImageRole)
# ...
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
# ...
it = QtWidgets.QTableWidgetItem()
it.setData(ImageRole, pixmap)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.