我的 PyQt5 應用程式包含一堆不同型別的輸入欄位:QLineEdit、QSpinBox、QComboBox、QTableView 等。
如果用戶輸入資料或更改一個或多個欄位的內容并嘗試關閉視窗而不保存,我想提醒用戶。
我是否必須將textChanged信號的所有不同變化連接到某種簿記功能,還是有更簡單的方法?
編輯:有關事件序列的更多詳細資訊:
- UI 是從 Qt Designer .ui 檔案構建的,因此某些欄位具有默認值(如 QSpinBox、QDateEdit)
- 不同 QTableViews 的模型使用某些默認資料結構進行初始化,例如 的 2d 陣列
None或鍵都回傳的字典None - 從檔案存盤中加載一堆檔案,并將欄位設定為這些檔案的值。可能會出現檔案中不存在對應鍵的情況,因此不會設定該欄位。但也有可能檔案中的值恰好是默認值。
- 用戶更改某些欄位的內容,并且在存盤中保存檔案時將相應地更新。
我希望能夠判斷在第 3 步之后是否有任何欄位被修改,也就是說用戶進行了更改。我想避免將所有欄位與檔案存盤進行比較。
uj5u.com熱心網友回復:
對于存盤單個屬性的簡單小部件,解決方案是使用每個小部件的元物件的用戶屬性。
專案視圖需要自定義檢查來比較模型。
您需要創建一個需要監視更改的小部件串列,在初始化期間獲取值,然后在關閉時進行驗證。
為簡化起見,您可以為所有需要檢查的小部件設定動態屬性,以便您可以遍歷所有小部件,檢查該屬性是否已設定,并將這些小部件添加到串列中。要在 Designer 中向小部件添加自定義屬性,請選擇小部件并單擊屬性編輯器中的“ ”符號;在下面的示例中,我使用了一個帶有基本真實性檢查的布爾屬性(“validate”):記住未設定的屬性回傳None,因此在這種情況下,您還必須將屬性設定為True。
class Test(QtWidgets.QDialog):
def __init__(self, parent=None):
super().__init__(parent)
uic.loadUi('mapper.ui', self)
self.loadData()
def loadData(self):
# some stuff setting the initial values
# ...
# save the current values
self.fieldData = []
for widget in self.findChildren(QtWidgets.QWidget):
if not widget.property('validate'):
continue
if isinstance(widget, QtWidgets.QAbstractItemView):
model = widget.model()
if not model:
continue
data = []
for row in range(model.rowCount()):
rowData = []
data.append(rowData)
for column in range(model.columnCount()):
rowData.append(model.index(row, column).data())
self.fieldData.append((widget, data))
else:
property = widget.metaObject().userProperty()
self.fieldData.append((widget, widget.property(property.name())))
def ignoreChanges(self):
for widget, default in self.fieldData:
if isinstance(widget, QtWidgets.QAbstractItemView):
model = widget.model()
for row, rowData in enumerate(default):
for column, itemData in enumerate(rowData):
if model.index(row, column).data() != default:
break
else:
property = widget.metaObject().userProperty()
if widget.property(property.name()) != default:
break
else:
return True
res = QtWidgets.QMessageBox.question(self, 'Ignore changes',
'Fields have been modified, do you want to ignore?',
QtWidgets.QMessageBox.Ok|QtWidgets.QMessageBox.Cancel)
if res != QtWidgets.QMessageBox.Ok:
return False
return True
def reject(self):
if self.ignoreChanges():
super().reject()
def closeEvent(self, event):
if not self.ignoreChanges():
event.ignore()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/369253.html
上一篇:AndroidEspresso:java.lang.NoClassDefFoundError:決議失敗:Landroidx/test/platform/io/FileTestStorage;
