一旦设置了两个带有 QStyledItemDelegate 的验证器,QtableView 就会崩溃
QtableView crashes as soon two validators with QStyledItemDelegate are set
基于这个 Question 的答案,我更进一步,基于 QStyledItemDelegate 创建了两个单独的验证器,一个用于整数,一个用于双精度。
如果验证器是唯一的一组,那么每个验证器都可以完美地工作。一旦我尝试设置两个验证器(每个都在其单独的列中),整个应用程序就会崩溃。
import sys
from PyQt5.QtCore import QSize, Qt, pyqtSignal, QObject
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QMessageBox,\
QLineEdit, QWidget, QVBoxLayout, QDataWidgetMapper, QPushButton, QStyledItemDelegate
from PyQt5.QtGui import QIntValidator, QDoubleValidator
class ValidatedIntItemDelegate(QStyledItemDelegate):
def __init__(self, bottom, top):
QStyledItemDelegate.__init__(self)
self.bottom = bottom
self.top = top
def createEditor(self, widget, option, index):
editor = QLineEdit(widget)
validator = QIntValidator(self.bottom, self.top)
editor.setValidator(validator)
return editor
class ValidatedDoubleItemDelegate(QStyledItemDelegate):
def __init__(self, bottom, top, decimals=0):
QStyledItemDelegate.__init__(self)
self.bottom = bottom
self.top = top
self.decimals = decimals
def createEditor(self, widget, option, index):
editor = QLineEdit(widget)
validator = QDoubleValidator(self.bottom, self.top, self.decimals)
editor.setValidator(validator)
return editor
class SqlModel(QSqlTableModel):
def __init__(self, parent=None):
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("chinook.sqlite")
self.db.open()
super().__init__()
self.setupTable()
self.setTable("Track")
self.setSort(1, Qt.AscendingOrder)
self.select()
self.setEditStrategy(QSqlTableModel.OnFieldChange)
def setupTable(self):
query = QSqlQuery()
query.exec("DROP TABLE if exists Track;")
query.exec("create table if not exists Track ("
"doda Text,"
"One Text,"
"Two Text,"
"Three Text);")
query.exec("INSERT into Track (doda) Values( '1' );")
query.exec("INSERT into Track (doda) Values( '2' );")
query.exec("INSERT into Track (doda) Values( '3' );")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setMinimumSize(QSize(450, 200))
widget = QWidget()
layout = QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.table = QTableView()
layout.addWidget(self.table)
self.model = SqlModel()
self.table.setModel( self.model )
intDelegate = ValidatedIntItemDelegate(1, 99)
self.table.setItemDelegateForColumn(0, intDelegate)
# doubleDelegate = ValidatedDoubleItemDelegate(1,99,2)
# self.table.setItemDelegateForColumn(1, doubleDelegate)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
有人知道如何让两个验证器并行工作吗?
问题似乎是因为视图没有取得委托的所有权,然后它们被从内存中删除,因为它们是局部变量,导致分段错误。解决方案是通过使 class 属性延长其生命周期:
<b>self.</b>intDelegate = ValidatedIntItemDelegate(1, 99)
self.table.setItemDelegateForColumn(0, <b>self.</b>intDelegate)
<b>self.</b>doubleDelegate = ValidatedDoubleItemDelegate(1, 99, 2)
self.table.setItemDelegateForColumn(1, <b>self.</b>doubleDelegate)
基于这个 Question 的答案,我更进一步,基于 QStyledItemDelegate 创建了两个单独的验证器,一个用于整数,一个用于双精度。
如果验证器是唯一的一组,那么每个验证器都可以完美地工作。一旦我尝试设置两个验证器(每个都在其单独的列中),整个应用程序就会崩溃。
import sys
from PyQt5.QtCore import QSize, Qt, pyqtSignal, QObject
from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlQuery
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QMessageBox,\
QLineEdit, QWidget, QVBoxLayout, QDataWidgetMapper, QPushButton, QStyledItemDelegate
from PyQt5.QtGui import QIntValidator, QDoubleValidator
class ValidatedIntItemDelegate(QStyledItemDelegate):
def __init__(self, bottom, top):
QStyledItemDelegate.__init__(self)
self.bottom = bottom
self.top = top
def createEditor(self, widget, option, index):
editor = QLineEdit(widget)
validator = QIntValidator(self.bottom, self.top)
editor.setValidator(validator)
return editor
class ValidatedDoubleItemDelegate(QStyledItemDelegate):
def __init__(self, bottom, top, decimals=0):
QStyledItemDelegate.__init__(self)
self.bottom = bottom
self.top = top
self.decimals = decimals
def createEditor(self, widget, option, index):
editor = QLineEdit(widget)
validator = QDoubleValidator(self.bottom, self.top, self.decimals)
editor.setValidator(validator)
return editor
class SqlModel(QSqlTableModel):
def __init__(self, parent=None):
self.db = QSqlDatabase.addDatabase("QSQLITE")
self.db.setDatabaseName("chinook.sqlite")
self.db.open()
super().__init__()
self.setupTable()
self.setTable("Track")
self.setSort(1, Qt.AscendingOrder)
self.select()
self.setEditStrategy(QSqlTableModel.OnFieldChange)
def setupTable(self):
query = QSqlQuery()
query.exec("DROP TABLE if exists Track;")
query.exec("create table if not exists Track ("
"doda Text,"
"One Text,"
"Two Text,"
"Three Text);")
query.exec("INSERT into Track (doda) Values( '1' );")
query.exec("INSERT into Track (doda) Values( '2' );")
query.exec("INSERT into Track (doda) Values( '3' );")
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setMinimumSize(QSize(450, 200))
widget = QWidget()
layout = QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.table = QTableView()
layout.addWidget(self.table)
self.model = SqlModel()
self.table.setModel( self.model )
intDelegate = ValidatedIntItemDelegate(1, 99)
self.table.setItemDelegateForColumn(0, intDelegate)
# doubleDelegate = ValidatedDoubleItemDelegate(1,99,2)
# self.table.setItemDelegateForColumn(1, doubleDelegate)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
有人知道如何让两个验证器并行工作吗?
问题似乎是因为视图没有取得委托的所有权,然后它们被从内存中删除,因为它们是局部变量,导致分段错误。解决方案是通过使 class 属性延长其生命周期:
<b>self.</b>intDelegate = ValidatedIntItemDelegate(1, 99)
self.table.setItemDelegateForColumn(0, <b>self.</b>intDelegate)
<b>self.</b>doubleDelegate = ValidatedDoubleItemDelegate(1, 99, 2)
self.table.setItemDelegateForColumn(1, <b>self.</b>doubleDelegate)