由于某些奇怪的原因,无法覆盖QListView
中突出显示的文字颜色。它运行正常(突出显示的文本颜色自动更改为白色),直到我定义自己的小部件来表示一行。
现在我可以更改所选行的背景颜色和其他一些视觉方面,但文本颜色始终保持默认黑色。
已经尝试使用QSS
,QPalette
和data()
/ Qt.ForegroundRole
完成所有操作 - 没有技巧有帮助。
这是一个简化的代码,仍然存在OS X
上的问题。很遗憾,我没有机会在Windows
或GNU/Linux
上进行测试。
from PySide.QtCore import *
from PySide.QtGui import *
import sys
view = None
mapp = {}
style = '''
QListView {
show-decoration-selected: 1;
selection-color: white;
selection-background-color: #0068d9;
}
QListView::item:selected:active:hover{
background-color:red; color: white;
}
QListView::item:selected:active:!hover{
background-color: #0068d9; color: white;
}
QListView::item:selected:!active{
background-color:yellow; color: white;
}
QListView::item:!selected:hover{
background-color:green; color: white;
}
'''
class SimpleListModel(QAbstractListModel):
def __init__(self, mlist):
QAbstractListModel.__init__(self)
self._items = mlist
def rowCount(self, parent = QModelIndex()):
return len(self._items)
def index(self, row, column, parent=QModelIndex()):
node = self._items[row]
if not(str(row) in mapp):
index = self.createIndex(row, column)
widget = QLabel(node)
view.setIndexWidget(index, widget)
mapp[str(row)] = index
return index
return mapp[str(row)]
def data(self, index, role = Qt.DisplayRole):
return None
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEnabled
class MyMainWindow(QWidget):
def __init__(self):
global view
QWidget.__init__(self, None)
self._model = SimpleListModel(["test", "tes1t", "t3est", "t5est", "t3est"])
vbox = QVBoxLayout()
view = QListView()
view.setModel(self._model)
vbox.addWidget(view)
self.setLayout(vbox)
view.setStyleSheet(style)
first = self._model.index(0, 0)
view.setCurrentIndex(first)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyMainWindow()
w.show()
w.raise_()
app.exec_()
sys.exit()
答案 0 :(得分:3)
不是最干净或最好的解决方案,但这是经过一些调整后我带来的。
结果:
蓝色项目是选定的项目。绿色项目是悬停的项目。
代码:
from PySide.QtCore import *
from PySide.QtGui import *
import sys
view = None
mapp = {}
style = '''
QListView {
show-decoration-selected: 1;
selection-color: white;
selection-background-color: #0068d9;
}
QListView::item:selected:active:hover{
background-color:red; color: white;
}
QListView::item:selected:active:!hover{
background-color: #0068d9; color: white;
}
QListView::item:selected:!active{
background-color:yellow; color: white;
}
QListView::item:!selected:hover{
background-color:green; color: white;
}
'''
class SimpleListModel(QAbstractListModel):
def __init__(self, mlist):
QAbstractListModel.__init__(self)
self._items = mlist
def rowCount(self, parent = QModelIndex()):
return len(self._items)
def index(self, row, column, parent=QModelIndex()):
node = self._items[row]
if not(str(row) in mapp):
index = self.createIndex(row, column)
widget = QLabel(node)
view.setIndexWidget(index, widget)
mapp[str(row)] = index
return index
return mapp[str(row)]
def data(self, index, role = Qt.DisplayRole):
# The following code shouldn't be put in this function but i'm in a hurry right now...
selectedIndexes = view.selectedIndexes()
# Set all items to black
for i in range(0, self.rowCount()):
currentRowIndex = self.index(i, 0, QModelIndex())
myWidget = view.indexWidget(currentRowIndex)
myWidget.setStyleSheet("color: black")
# Set selected items to white
for i in selectedIndexes:
myWidget = view.indexWidget(i)
myWidget.setStyleSheet("color: white")
return None
def flags(self, index):
return Qt.ItemIsSelectable | Qt.ItemIsEnabled
class MyMainWindow(QWidget):
def __init__(self):
global view
QWidget.__init__(self, None)
self._model = SimpleListModel(["test", "tes1t", "t3est", "t5est", "t3est"])
vbox = QVBoxLayout()
view = QListView()
view.setModel(self._model)
vbox.addWidget(view)
self.setLayout(vbox)
view.setStyleSheet(style)
first = self._model.index(0, 0)
view.setCurrentIndex(first)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyMainWindow()
w.show()
w.raise_()
app.exec_()
sys.exit()
请告诉我是否有我无法正确理解的内容或代码不够清晰。
答案 1 :(得分:2)
第一: 您的代码以相同的方式处理GNU / Linux(Ubuntu 14.04 LTS,PyQt5)。
由于文字已写入indexWidget
,因此必须为text-color
设置QLabel
的样式表。
由于QLabel
不支持悬停伪状态,因此无法以与项目相同的方式完成。
为选定的indexWidgets
设置样式表我使用了信号槽机制,对于悬停的indexWidgets
,我使用了事件过滤器,
只修改了MyMainWindow类:
class MyMainWindow(QWidget):
def __init__(self):
global view
QWidget.__init__(self, None)
self._model = SimpleListModel(["test", "tes1t", "t3est", "t5est", "t3est"])
vbox = QVBoxLayout()
view = QListView()
view.setModel(self._model)
view.setMouseTracking(True) # to catch mouseEvents
view.installEventFilter(self) # for events in ListView
vbox.addWidget(view)
self.setLayout(vbox)
view.setStyleSheet(style)
first = self._model.index(0, 0)
view.setCurrentIndex(first)
view.clicked.connect(self.setIndexStyle) # or any other signal
def setIndexStyle(self, index):
for i in range(0,view.model().rowCount()):
style = 'color: black;'
view.indexWidget(view.model().index(i,0)).setStyleSheet(style)
for i in view.selectedIndexes(): # works for multiseletion too
style = 'color: white;'
view.indexWidget(i).setStyleSheet(style)
def eventFilter(self,obj,event):
if event.type() == QEvent.HoverMove and isinstance(obj,QListView):
i = view.indexAt(event.pos()) # index at mouse.pos()
self.setIndexStyle(i) # selected indexWidgets still have white text
style = 'color: white;'
try: # if no item on mouse.pos()
view.indexWidget(i).setStyleSheet(style)
except AttributeError:
pass
return False
return QWidget.eventFilter(self,obj,event)