我想自定义QTableView的外观。因此,我决定禁用网格线并自己进行绘画。我将QStyledItemDelegate子类化并重新实现其paint方法。一切正常,直到我在表格中选择一些单元格。选择不知何故弄乱了这幅画......
最后,我提供了一个小的演示应用程序。
如果您运行该应用程序,只需单击名为“Night”的单元格,您就会明白我的意思。我怎么能改变呢?
我想在用户选择一个单元格之后调用重新绘制,但这不起作用。
如果有人可以帮助我,我真的很感激。非常感谢!
main.py
from PyQt4 import QtCore
from PyQt4 import QtGui
import sys
from productiontable import productionTableModel
from productiontable import productionTableBorder
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
tableview = QtGui.QTableView()
model = productionTableModel([["Prod. 1"], ["Prod. 2"], ["Prod. 3"], ["Prod. 4"], ["Prod. 5"]])
tableview.setModel(model)
tableview.resizeColumnsToContents()
tableview.verticalHeader().setVisible(False)
tableview.horizontalHeader().setVisible(False)
tableview.setFrameStyle(QtGui.QFrame.NoFrame)
tableview.setShowGrid(False)
tableview.setFocusPolicy(QtCore.Qt.NoFocus) #remove dotted line, when cell has focus
tableview.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
d = productionTableBorder()
tableview.setItemDelegate(d)
tableview.resize(100, 300)
tableview.show()
sys.exit(app.exec_())
productiontable.py
from PyQt4 import QtCore
from PyQt4 import QtGui
class productionTableBorder(QtGui.QStyledItemDelegate):
def __init__(self, parent = None):
QtGui.QStyledItemDelegate.__init__(self, parent)
def paint(self, painter, option, index):
QtGui.QStyledItemDelegate.paint(self, painter, option, index)
if index.row()%2 == 0:
painter.save()
painter.setPen(QtGui.QPen(QtCore.Qt.white, 4))
#draw a white line from start to end
start = QtCore.QPoint(option.rect.x(), option.rect.y())
end = QtCore.QPoint(option.rect.x() + option.rect.width(), option.rect.y())
painter.drawLine(start, end)
painter.restore()
class productionTableModel(QtCore.QAbstractTableModel):
def __init__(self, lst = [[]], parent = None):
QtCore.QAbstractTableModel.__init__(self, parent)
self.__lst = lst
def rowCount(self, parent = None):
return len(self.__lst) * 2
def columnCount(self, parent = None):
return 2
def data(self, index, role):
col = index.column()
row = index.row()
if role == QtCore.Qt.DisplayRole:
if col == 0:
if row%2 == 0:
return self.__lst[row/2][col]
if col == 1:
if row%2 == 0:
return "Day"
else:
return "Night"
if role == QtCore.Qt.BackgroundRole:
return QtGui.QColor(188, 250, 213)
def flags(self, index):
return (QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.NoItemFlags)
答案 0 :(得分:0)
好的,我明白了。
要绘制自己的网格线,需要子类QTableView ,子类化QStyledItemDelegate不起作用!如果您继承QStyledItemDelegate并覆盖其paint()方法,则还需要重新计算单元格的大小(因为网格线)。
更好地继承QTableView并在paintEvent中绘制网格线。
这是我的解决方案(受this主题启发):
<强> main.py 强>
from PyQt4 import QtCore
from PyQt4 import QtGui
import sys
from productiontable import productionTableModel
from productiontable import customTable
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
tableview = customTable()
model = productionTableModel([["Prod. 1"], ["Prod. 2"], ["Prod. 3"], ["Prod. 4"], ["Prod. 5"]])
tableview.setModel(model)
tableview.resizeColumnsToContents()
tableview.verticalHeader().setVisible(False)
tableview.horizontalHeader().setVisible(False)
tableview.setFrameStyle(QtGui.QFrame.NoFrame)
tableview.setShowGrid(False)
tableview.setFocusPolicy(QtCore.Qt.NoFocus) #remove dotted line, when cell has focus
tableview.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
tableview.resize(100, 300)
tableview.show()
sys.exit(app.exec_())
productiontable.py
from PyQt4 import QtCore
from PyQt4 import QtGui
class customTable(QtGui.QTableView):
def __init__(self, parent = None):
QtGui.QTableView.__init__(self, parent)
def paintEvent(self, event):
super(customTable, self).paintEvent(event)
#set the pen
pen = QtGui.QPen(QtCore.Qt.white, 4)
# Create the painter
painter = QtGui.QPainter(self.viewport())
# Shortcuts to vertical and horizontal headers
vh = self.verticalHeader()
hh = self.horizontalHeader()
# Get the first and last rows that are visible in the view and if the
# last visiable row returns -1 set it to the row count
firstVisualRow = max([vh.visualIndexAt(0), 0])
lastVisualRow = vh.visualIndexAt(vh.viewport().height())
if lastVisualRow == -1:
lastVisualRow = self.model().rowCount(self.rootIndex()) - 1
# Get the first and last columns that are visible in the view and if
# if the last visible column is -1 set it to the column count.
firstVisualColumn = max([hh.visualIndexAt(0), 0])
lastVisualColumn = hh.visualIndexAt(hh.viewport().width())
if lastVisualColumn == -1:
lastVisualColumn = hh.count() - 1
# Iterate through each row and column drawing only the
# bottom and left side lines for each cell. Skipping rows and columns
# that are hidden
for vrow in xrange(firstVisualRow, lastVisualRow + 1, 2):
row = vh.logicalIndex(vrow)
FirstRow = (vrow == 0)
if vh.isSectionHidden(row):
continue
# Get top left Y coordinate and row height
rowY = self.rowViewportPosition(row)
rowh = self.rowHeight(row)
for vcol in range(firstVisualColumn, lastVisualColumn + 1):
col = hh.logicalIndex(vcol)
FirstColumn = (vcol == 0)
if hh.isSectionHidden(col):
continue
# Get top left X coordinate and column width
colX = self.columnViewportPosition(col)
colw = self.columnWidth(col)
# Get the model index
index = self.model().createIndex(row, col)
# Specify top, bottom, left and right of the cell
top = rowY
bottom = rowY
left = colX
right = colX + colw
# Save the painter and set the pen
painter.save()
painter.setPen(pen)
# Draw Horizontal Lines
painter.drawLine(left, bottom, right, bottom)
# Restore painter
painter.restore()
class productionTableModel(QtCore.QAbstractTableModel):
def __init__(self, lst = [[]], parent = None):
QtCore.QAbstractTableModel.__init__(self, parent)
self.__lst = lst
def rowCount(self, parent = None):
return len(self.__lst) * 2
def columnCount(self, parent = None):
return 2
def data(self, index, role):
col = index.column()
row = index.row()
if role == QtCore.Qt.DisplayRole:
if col == 0:
if row%2 == 0:
return self.__lst[row/2][col]
if col == 1:
if row%2 == 0:
return "Day"
else:
return "Night"
if role == QtCore.Qt.BackgroundRole:
return QtGui.QColor(188, 250, 213)
def flags(self, index):
return (QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable)