QTableWidget 和 setCellWidget:调整大小问题
Posted
技术标签:
【中文标题】QTableWidget 和 setCellWidget:调整大小问题【英文标题】:QTableWidget and setCellWidget: resize problem 【发布时间】:2020-06-28 16:17:59 【问题描述】:我尝试在 QTableWidget 的某个单元格中插入一些 QRadioButton。情况类似于this post 的情况。特别是@eyllanesc 的解决方案,PySide2
如下
import sys
from PySide2.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, \
QButtonGroup, QRadioButton
app = QApplication(sys.argv)
searchView = QTableWidget(0, 4)
colsNames = ['A', 'B', 'C']
searchView.setHorizontalHeaderLabels(['DIR'] + colsNames)
dirNames = 'A': ['/tmp', '/tmp/dir1'], 'B': ['/tmp/dir2'],
'C': ['/tmp/dir3']
rowCount = sum(len(v) for (name, v) in dirNames.items())
searchView.setRowCount(rowCount)
index = 0
for letter, paths in dirNames.items():
for path in paths:
it = QTableWidgetItem(path)
searchView.setItem(index, 0, it)
group = QButtonGroup(searchView)
for i, name in enumerate(colsNames):
button = QRadioButton()
group.addButton(button)
searchView.setCellWidget(index, i + 1, button)
if name == letter:
button.setChecked(True)
index += 1
searchView.show()
sys.exit(app.exec_())
在调整列或行的大小时,我注意到一个奇怪的行为:当我按下鼠标按钮并调整列或原始大小时,QRadioButtons 仍然在它们的位置,导致一些冲突;然后,当我最终松开鼠标按钮时,每个 QRadioButton 都会到位。有没有办法避免在调整大小的过程中也让 QRadioButtons 移动?
【问题讨论】:
【参考方案1】:由于我之前的解决方案会产生其他问题,因此在此解决方案中,我将展示另一种选择:
使用 Qt :: CheckStateRole 通过委托实现排除逻辑。 QProxyStyle 可用于绘画import sys
from PySide2.QtCore import Qt, QEvent
from PySide2.QtWidgets import (
QApplication,
QTableWidget,
QTableWidgetItem,
QStyledItemDelegate,
QStyle,
QStyleOptionViewItem,
QProxyStyle,
)
class RadioButtonDelegate(QStyledItemDelegate):
def editorEvent(self, event, model, option, index):
flags = model.flags(index)
if (
not (flags & Qt.ItemIsUserCheckable)
or not (option.state & QStyle.State_Enabled)
or not (flags & Qt.ItemIsEnabled)
):
return False
state = index.data(Qt.CheckStateRole)
if state is None:
return False
widget = option.widget
style = widget.style() if widget is not None else QApplication.style()
# make sure that we have the right event type
if (
(event.type() == QEvent.MouseButtonRelease)
or (event.type() == QEvent.MouseButtonDblClick)
or (event.type() == QEvent.MouseButtonPress)
):
viewOpt = QStyleOptionViewItem(option)
self.initStyleOption(viewOpt, index)
checkRect = style.subElementRect(
QStyle.SE_ItemViewItemCheckIndicator, viewOpt, widget
)
me = event
if me.button() != Qt.LeftButton or not checkRect.contains(me.pos()):
return False
if (event.type() == QEvent.MouseButtonPress) or (
event.type() == QEvent.MouseButtonDblClick
):
return True
else:
return False
if state != Qt.Checked:
for c in range(model.columnCount()):
if c not in (0, index.column()):
ix = model.index(index.row(), c)
model.setData(ix, Qt.Unchecked, Qt.CheckStateRole)
return model.setData(index, Qt.Checked, Qt.CheckStateRole)
return False
class Radiostyle(QProxyStyle):
def drawPrimitive(self, element, option, painter, widget=None):
if element == QStyle.PE_IndicatorItemViewItemCheck:
element = QStyle.PE_IndicatorRadioButton
super().drawPrimitive(element, option, painter, widget)
app = QApplication(sys.argv)
searchView = QTableWidget(0, 4)
style = RadioStyle(searchView.style())
searchView.setStyle(style)
delegate = RadioButtonDelegate(searchView)
searchView.setItemDelegate(delegate)
colsNames = ["A", "B", "C"]
searchView.setHorizontalHeaderLabels(["DIR"] + colsNames)
dirNames = "A": ["/tmp", "/tmp/dir1"], "B": ["/tmp/dir2"], "C": ["/tmp/dir3"]
rowCount = sum(len(v) for (name, v) in dirNames.items())
searchView.setRowCount(rowCount)
index = 0
for letter, paths in dirNames.items():
for path in paths:
it = QTableWidgetItem(path)
searchView.setItem(index, 0, it)
for i, name in enumerate(colsNames):
it = QTableWidgetItem()
searchView.setItem(index, i + 1, it)
it.setCheckState(Qt.Checked if name == letter else Qt.Unchecked)
index += 1
searchView.show()
sys.exit(app.exec_())
【讨论】:
不错的解决方案,因为我是初学者,所以我必须研究它。一个问题:“原始”解决方案有什么问题?调整大小过程中的奇怪行为是错误还是类似的东西? (只是为了理解和学习) @MaPo 似乎只有在释放鼠标时才通知单元格小部件的大小(宽度)变化,虽然这个问题可以解决我更喜欢实现更优化的解决方案跨度> 只是循序渐进地学习,我应该阅读什么来修改原始示例以避免'延迟'发布通知?以上是关于QTableWidget 和 setCellWidget:调整大小问题的主要内容,如果未能解决你的问题,请参考以下文章
QTableWidget 和 QHeaderView CSS
QTableWidget 和 setCellWidget:调整大小问题