Python 如何监控变化?

Python 如何监控变化?,python,python-3.x,pyqt,pyqt5,Python,Python 3.x,Pyqt,Pyqt5,背景故事: 我目前正在开发一个程序,它有几个qComboBox和qLineEdit元素,用户可以在其中输入数据或选择值。当用户选择“新建文件”或“打开文件”时,我想检查是否有任何值已更改,并向用户提供保存其工作的选项。输出文件是XML 问题: 基本上,我只需要知道是否有任何值与默认值不同。我不关心确切的值有什么不同,我只需要知道它们是不同的 我尝试使用xmldiff,在程序启动时创建一个包含初始值的元素树,然后将其与第二个元素树和当前值进行比较。它似乎不能给出一个真值或假值,第二个元素树的大小也

背景故事:

我目前正在开发一个程序,它有几个
qComboBox
qLineEdit
元素,用户可以在其中输入数据或选择值。当用户选择“新建文件”或“打开文件”时,我想检查是否有任何值已更改,并向用户提供保存其工作的选项。输出文件是XML

问题:

基本上,我只需要知道是否有任何值与默认值不同。我不关心确切的值有什么不同,我只需要知道它们是不同的

我尝试使用xmldiff,在程序启动时创建一个包含初始值的元素树,然后将其与第二个元素树和当前值进行比较。它似乎不能给出一个真值或假值,第二个元素树的大小也不一样,所以我不认为我可以简单地进行1对1的比较

我尝试的第二件事是在元素更改时简单地设置一个布尔值,但我无法解释将元素重置为默认值的原因。例如,如果一个
qLineEdit
框没有值,而用户输入了一些东西,则会将布尔值设置为“true”;但是,如果他们返回并将该值更改回默认值,则结果也将为“true”

我想知道是否有做这类事情的“最佳实践”,或者是否有人能为我指出正确的方向。这似乎在很大程度上应该是微不足道的,但我不知道如何处理这个问题

编辑…添加了第二次尝试的示例

import sys
from PyQt5.QtWidgets import *


class Window(QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.modified = False
        self.edit1 = QLineEdit()
        layout = QGridLayout(self)
        layout.addWidget(self.edit1)

        self.edit1.editingFinished.connect(self.valueChanged)

    def valueChanged(self):
        print('valueChanged Event')
        self.modified = True

    def closeEvent(self, event):
        if self.modified:
            prompt = QMessageBox.warning(
                self, 'Save Changes?',
                'This document has been modified.\n'
                'Do you want to save these changes?',
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel, QMessageBox.Cancel
        )

            if prompt == QMessageBox.Yes:
                event.accept()
            if prompt == QMessageBox.No:
                event.accept()
            if prompt == QMessageBox.Cancel:
                event.ignore()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.setGeometry(600, 100, 300, 100)
    window.show()
    sys.exit(app.exec_())
带有默认值的成员dict: 用
{qline1Name:“tata”,qcombo:2,…}
创建一个
dict
。它将您的
实例
作为键及其初始值保存。保存时,检查当前值是否与存储在其中的值不同,并采取相应措施。您必须区分两个用作输入元素的类-对于combobox,可以使用初始选择的索引

衍生/猴子补丁/装饰: 您可以派生/修补/修饰Q*-输入,并向其添加
default\u值
属性。创建时设置,保存时评估:

(Mis-)使用现有字段: QLineEdit提供了一个可以用于“defaultvalue”并进行简单比较的选项(除非您的defaultText是空格,否则它们会被禁用)


更通用的方法是利用QString字段。这样,所有输入元素只能使用一个属性,如果isinstance(…):将其与实际输入元素进行比较时,可以转换其QString值。

如果要提供一个最小的示例,并显示实际尝试的不同内容(关键是使其最小化),这将是一个好问题。没有任何对话框或XML内容真正需要显示。只是做一些最低限度的运行。我不太明白为什么这会得到这么多接近票。。。问题很清楚,提供的代码显示了已经做了什么,并演示了问题。如果在文本框中输入smth,则会显示关闭时的弹出窗口,如果再次清除文本框,则仍会显示:这是不需要的行为。有几种方法可以实现所需的功能,并且问题很容易回答——无论是在代码中还是在对话中。@PatrickArtner我建议您不仅要考虑问题的当前状态,还要了解问题有一个生命周期,也就是说,您是在限定当前问题,而不是初始问题,也许那些投票关闭的人只看到了前一个没有MCVE的州我想这部分是我的错。我试图解释一个复杂的问题,我没有写一本关于正在发生什么的小说。没有必要重新发明轮子或求助于黑客:Qt提供了一个通用的,旨在解决这类问题。我曾考虑过使用字典来解决这类问题,但我不认为这是最有效的方法。我也没有试图在代码中实现任何黑客行为。我希望尽可能保持事情的干净和易懂@Ekhumaro,我读过撤销/重做框架,但我不确定这对解决问题有什么帮助。如果我只需执行
xmlTree1!=xmlTree2
并根据比较得到一个真值或假值。我想我主要寻找的是在程序运行期间处理更改检测的行业标准。@AaronTomason你确定你真的读过吗?撤销堆栈的设计正是为了处理程序运行期间的更改检测。@ekhumoro我看到了你所说的,但我仍然在用一个最小的程序来解决它。我以前没有使用过
QUndoStack
,似乎我可以使用
isClean()
和保存时的设置标志来跟踪是否发生了“更改”以重置状态。我仍然不知道是否可以使用它来检测某个值是否等于默认值。似乎这需要在每个变更方法中实现。