【发布时间】:2016-11-27 19:43:39
【问题描述】:
我第一次在 PyQt 中处理表格,在编辑单元格值时遇到了一些意外行为。
特别是当我输入数据时,它出现在现有单元格数据的顶部(因此,如果单元格中最初包含“123”,而我输入“456”,我最终会得到 2 批 3 个字符,一个在另一个之上 - 至少在我按下回车键之前)。
为了清楚起见,我对 setData 将更改写入模型没有任何问题,或者在编辑完成后将更改反映在表格中 - 这一切都很好。唯一的问题是看到我输入的原始值和新值占用相同的空间,直到编辑完成。
所以大概我想做的是改变我现有的数据方法:
def data(self, index, int_role=None):
row = index.row()
column = index.column()
if int_role == QtCore.Qt.DisplayRole:
return str(self._data[row][column])
elif int_role == QtCore.Qt.EditRole:
return str(self._data[row][column])
else:
return None
以便它以某种方式识别它被要求为其提供数据的单元格(在 DisplayRole 模式下)当前是否正在被编辑,如果是,则返回一个空字符串而不是实际数据(因为代码的 EditRole 分支是同时也被调用并愉快地处理显示任务,直到编辑完成)。
我查看了 QT 文档,但不知道如何执行此操作。
编辑:在 ceppo 的 cmets 之后,我考虑创建一个新的 ItemDelegate - 但looking into it further 看起来我可以在现有的项目中切换 itemEditorFactory - 特别是我在我的代码中添加了以下内容:
newEditor = QLineEdit()
newEditor.setAutoFillBackground(True)
ief = QItemEditorFactory()
ief.registerEditor(QVariant.String, LineEditorCreator())
tableView.itemDelegate().setItemEditorFactory(ief)
LineEditorCreator 定义如下:
class LineEditCreator(QItemEditorCreatorBase):
def __init__(self):
QItemEditorCreatorBase.__init__(self)
def createWidget(self, parent):
wdgt = QLineEdit(parent)
wdgt.setAutoFillBackground(True)
return wdgt
def valuePropertyName(self):
return "String"
但是,现在我一尝试编辑单元格值就会出现分段错误。将 print 语句作为 createWidget 语句的第一行显示它永远不会执行 - createWidget 中的一些打印语句表明分段错误甚至在 createWidget 的第一行执行之前发生(尽管 __ init __ 方法完成得很好) .
Ceppo 还说我遇到的行为可能是由于错误(在 Qt、PyQt 或其他底层)造成的 - 我将很快用 16.04 替换我当前的 Ubuntu 15.10 安装,所以运气好的话可以解决完全是问题。
【问题讨论】:
-
可能是编辑器背景有问题,尝试添加
BackgroundRole并返回一个颜色(例如红色),如果编辑器有透明背景,编辑时会看到那个颜色。 -
我在
int_role == QtCore.Qt.BackgroundRole的子句中添加了另一个 elif 分支,并在其中添加了return QColor(255,0,0,255)- 这确实使所有单元格的背景一直变红,无论它们是是否正在编辑 - 但这并不能真正帮助实现在编辑器可见时使单元格内容不可见的目标。我知道如果我可以将编辑器的背景设置为可以工作的窗口背景颜色,但我不知道如何在 EditRole 分支中设置编辑器的背景颜色(或者根本不知道如何引用编辑器)。跨度> -
是找到问题的根源(可能是你的qt版本的bug?我没有这个问题);)无论如何你不能直接从模型改变编辑器的背景,但是你可以写一个简单的
LineEditeditor-delegate 然后你可以在这里找到解决方案:stackoverflow.com/questions/22805756/…
标签: qt pyqt pyqt5 qtableview