在下面的python2.7、PyQt4示例中,我生成了2个QTableWidgets。表1没有ItemDelegate,表2有HTMLDelegate。你知道吗
如果表格具有焦点,则选定的背景色起作用,但当表格失去焦点时,蓝色选择在table2上变为灰色。当焦点丢失时,我希望table2选择像table1一样工作。你知道吗
使用itemdegate时,如何保持蓝色选择外观而不考虑焦点?你知道吗
import sip
sip.setapi('QVariant', 2)
from PyQt4 import QtCore, QtGui
import random
from html import escape
words = [
"Hello",
"world",
"Stack",
"Overflow",
"Hello world",
]
class HTMLDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(HTMLDelegate, self).__init__(parent)
self.doc = QtGui.QTextDocument(self)
def paint(self, painter, option, index):
col = index.column()
row = index.row()
painter.save()
options = QtGui.QStyleOptionViewItem(option)
self.initStyleOption(options, index)
text = index.data()
self.doc.setHtml(text)
options.text = ""
style = (
QtGui.QApplication.style()
)
style.drawControl(QtGui.QStyle.CE_ItemViewItem, options, painter)
ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
if option.state & QtGui.QStyle.State_Selected:
ctx.palette.setColor(QtGui.QPalette.Text, option.palette.color(QtGui.QPalette.Active, QtGui.QPalette.HighlightedText), )
else:
ctx.palette.setColor(QtGui.QPalette.Text, option.palette.color(QtGui.QPalette.Active, QtGui.QPalette.Text), )
textRect = (options.rect)
constant = 4
margin = (option.rect.height() - options.fontMetrics.height()) // 2
margin = margin - constant
textRect.setTop(textRect.top() + margin)
painter.translate(textRect.topLeft())
painter.setClipRect(textRect.translated(-textRect.topLeft()))
self.doc.documentLayout().draw(painter, ctx)
painter.restore()
def sizeHint(self, option, index):
return QSize(self.doc.idealWidth(), self.doc.size().height())
class Widget(QtGui.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
hlay = QtGui.QHBoxLayout()
lay = QtGui.QVBoxLayout(self)
self.table1 = QtGui.QTableWidget(4, 2)
self.table2 = QtGui.QTableWidget(4, 2)
lay.addLayout(hlay)
lay.addWidget(self.table1)
lay.addWidget(self.table2)
# define itemdelegate for table1, but not for table2
self.table2.setItemDelegate(HTMLDelegate(self.table2))
# fill table1
for i in range(self.table1.rowCount()):
for j in range(self.table1.columnCount()):
it = QtGui.QTableWidgetItem(random.choice(words))
self.table1.setItem(i, j, it)
# fill table2
for i in range(self.table2.rowCount()):
for j in range(self.table2.columnCount()):
it = QtGui.QTableWidgetItem(random.choice(words))
self.table2.setItem(i, j, it)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setStyle("Plastique") # set style
stylesheet = """
QPushButton:hover, QComboBox:hover
{
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #cbc9c5, stop: 1 #b9b7b5);
border: 2px solid #78879b;
border-radius: 3px;
}
QTableWidget::item:selected
{
background: #0078d7;
color: white;
}
QTableWidget
{
font: 9pt "Segoe UI";
}
QHeaderView
{
font: 9pt "Segoe UI";
}
"""
app.setStyleSheet(stylesheet)
myapp = Widget()
myapp.show()
rc = app.exec_()
myapp.close()
sys.exit(rc)
您正在使用} ,它实现了许多有用的东西,包括装饰(如在item icon中)及其位置、根据其他项的项位置,最重要的是,委托所使用的小部件及其完整的QStyle绘制功能。你知道吗
QStyleOptionViewItem
,它在Qt4中是一个非常基本的类,而您需要的是^{style.drawControl
方法和大多数QStyle方法一样,也有一个widget
参数;它通常被忽略,但在这种情况下非常重要,特别是在有样式表的情况下。你知道吗我建议您使用
option
方法的paint()
类作为参考来创建您自己的选项,该选项将自动使用ViewItem可用的最新QStyleOption,并且还将使将来可能更容易过渡到Qt5。你知道吗请记住,根据文档(这一点有点模糊),widget属性只能从QStyleOptionViewItem的版本3获得,但是根据我的测试,正确的背景绘制无论如何都会失败。如果出于任何原因,您一直使用Qt的一个非常的旧版本,它不提供QStyleOptionViewItemV4,恐怕您唯一的选择就是将背景色引用保留在某个地方(无法从代码中访问样式表颜色,它与QTableView
Highlight
调色板角色不匹配,并且自己手动绘制背景。你知道吗PS:我建议您不要对对象使用太相似的名称:我实际上找不到问题的根源,因为我经常混淆“option”和“options”:这就是我更改它的原因,这对于可读性和调试目的来说也更好。你知道吗
相关问题 更多 >
编程相关推荐