Python QtableView中不可编辑单元格上的选项卡
我正在使用PYQT5。我有一个QtableView小部件,用于快速输入数据,类似于电子表格。某些列可编辑,而其他列(标签等)不可编辑。我很简单地通过子类化QItemDelegate实现了这一点 我想做的是,当用户从一个可编辑的单元格中选择标签时,它将跳过任何不可编辑的单元格并转到下一个可编辑的单元格。我想我需要在编辑某个地方后检查一个按键事件,并确定下一个是哪个列。或者,当我在一个不可编辑的单元格中着陆时,我应该立即移动到下一个可编辑的单元格。我的代码是:Python QtableView中不可编辑单元格上的选项卡,python,qt,pyqt,pyqt5,Python,Qt,Pyqt,Pyqt5,我正在使用PYQT5。我有一个QtableView小部件,用于快速输入数据,类似于电子表格。某些列可编辑,而其他列(标签等)不可编辑。我很简单地通过子类化QItemDelegate实现了这一点 我想做的是,当用户从一个可编辑的单元格中选择标签时,它将跳过任何不可编辑的单元格并转到下一个可编辑的单元格。我想我需要在编辑某个地方后检查一个按键事件,并确定下一个是哪个列。或者,当我在一个不可编辑的单元格中着陆时,我应该立即移动到下一个可编辑的单元格。我的代码是: class Rates_sheet(Q
class Rates_sheet(QDialog, Ui_rates_sheet):
"""Displays rates for the next x days for quick changes"""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
QDialog.__init__(self)
self.ui = Ui_rates_sheet()
self.ui.setupUi(self)
self.ui.num_days.setValue(45)
self.ui.get_avail.clicked.connect(self.make_rate_sheet)
self.ui.publish_avail.clicked.connect(self.publish_rates)
self.populate()
def populate(self):
self.rates_model = QSqlTableModel()
self.rates_model.setTable("rates_sheet")
self.rates_model.select()
self.rates_view = self.ui.rates_grid
self.rates_view.setModel(self.rates_model)
self.rates_view.resizeColumnsToContents()
self.rates_view.setSortingEnabled(True)
self.rates_view.setColumnHidden(0, True)
for x in range(7,12):
self.rates_view.setColumnHidden(x, True)
self.rates_view.horizontalHeader().moveSection(3,10)
self.rates_view.horizontalHeader().moveSection(3,12)
self.rates_view.horizontalHeader().moveSection(13,2)
self.rates_view.setItemDelegate(Tmodel(self))
self.rates_model.setHeaderData(1, Qt.Horizontal, "Date")
self.rates_model.sort(1, Qt.AscendingOrder)
def make_rate_sheet(self):
pass
def publish_rates(self):
pass
class Tmodel(QItemDelegate):
"""Remplement rates_sheet table"""
def __init__(self, parent=None):
QItemDelegate.__init__(self)
def createEditor(self, parent, option, index):
if index.column() == 4:
spinbox = QSpinBox(parent)
spinbox.setRange(1,4)
return spinbox
elif index.column() in [5,6,11,12]:
spinbox = QSpinBox(parent)
spinbox.setRange(49,499)
return spinbox
编辑:
我尝试重新实现QSqlTableModel以更改标志中的值,但最终出现运行时错误:
class MySqlTableModel(QSqlTableModel):
def __init__(self):
QSqlTableModel.__init__(self)
def flags(self, index):
if index.isValid():
if index.column() == 4:
flags ^= 1
return flags
我得到的错误是:
File "f:\Dropbox\pms\main-5.py", line 2658, in <module>
sys.exit(app.exec_())
builtins.TypeError: invalid result from MySqlTableModel.flags(), NoneType cannot be converted to PyQt5.QtCore.ItemFlags in this context
文件“f:\Dropbox\pms\main-5.py”,第2658行,在
sys.exit(app.exec_())
builtins.TypeError:MySqlTableModel.flags()的结果无效,在此上下文中,无法将非类型转换为PyQt5.QtCore.ItemFlags
现在我更困惑了。在为此流汗了几天之后,答案是您可以成功地重新实现QsqlTableModel。下面是我如何得出答案的 首先,我看到了网络上的建议,主要是在C++的QT论坛上,你应该重新实现QSQL查询模型而不是QsqlTableModel。但是,您必须为setdata、data、rowcount、columncount、insertrows、deleterows创建方法,更不用说自己创建标志了。这似乎需要大量的工作,而且容易出错。我无法让它工作 考虑到以上所有内容都是毫无意义的,而且需要大量工作,我发现了一个代码片段,其中有人试图使用来自QsqlQueryModel的dataChanged信号,建议他们跳过QsqlTableModel。最后,我看到了一个例子,说明了如何准确地完成我正在尝试的事情。因此,我更新了我的代码如下:
class Rates_sheet(QDialog, Ui_rates_sheet):
"""Displays rates for the next x days for quick changes"""
def __init__(self):
"""Constructor"""
QDialog.__init__(self)
self.ui = Ui_rates_sheet()
self.ui.setupUi(self)
self.ui.num_days.setValue(45)
self.ui.get_avail.clicked.connect(self.make_rate_sheet)
self.ui.publish_avail.clicked.connect(self.publish_rates)
self.populate()
def populate(self):
self.rates_model = MySqlTableModel()
self.rates_model.setTable("rates_sheet")
self.rates_model.select()
self.rates_view = self.ui.rates_grid
self.rates_view.setModel(self.rates_model)
self.rates_view.resizeColumnsToContents()
self.rates_view.setSortingEnabled(True)
self.rates_view.setColumnHidden(0, True)
self.rates_view.setItemDelegate(Tmodel(self))
self.rates_model.setHeaderData(1, Qt.Horizontal, "Date")
self.rates_model.sort(1, Qt.AscendingOrder)
def make_rate_sheet(self):
pass
def publish_rates(self):
pass
class MySqlTableModel(QSqlTableModel):
"""Overides QSqlTableModel to make columns not selectable"""
def __init__(self):
QSqlTableModel.__init__(self)
def setData(self, index, value, role=Qt.EditRole):
if role == Qt.EditRole:
value = value.strip() if type(value) == str else value
return super(MySqlTableModel, self).setData(index, value, role)
def flags(self, index):
flags = super(MySqlTableModel, self).flags(index)
if index.column() in (4, 5, 6, 11):
flags |= Qt.ItemIsEditable
else:
flags &= Qt.ItemIsSelectable
return flags
这就是解决办法。我仍在测试,但还没有发现任何问题。据我所知,您可以实现模型的
标志
方法,并退出ItemsSelectable选项,这也有助于对其进行选项卡切换。看,我真的很困惑。我本以为一个项目是否可选择将是视图的工作。我正在努力重新实现QSqlTableModel并使其正常工作。你能提供更多PYQT的详细信息吗?Qt的处理方式有点不同,请参阅。关于PyQt我不适合你sry。但是阅读本文和这里的一些示例应该可以被Python采用。愿原力与你同在。