Hi,good evening, I have a application with many child widgets (QSpinBox,QLineEdit,QcomboBox,etc), can i detect if one of the widgets, and hence the application, has been modified?
Hi @Damian,
Modify in which aspect???
Each widget has its own event triggers:
QSpinBox:
- textChanged(const QString &text)
- valueChanged(int i)
QLineEdit:
- cursorPositionChanged(int oldPos, int newPos)
- editingFinished()
- inputRejected()
- returnPressed()
- selectionChanged()
- textChanged(const QString &text)
- textEdited(const QString &text)
QComboBox:
- activated(int index)
- currentIndexChanged(int index)
- currentTextChanged(const QString &text)
- editTextChanged(const QString &text)
- highlighted(int index)
- textActivated(const QString &text)
- textHighlighted(const QString &text)
You can subscribe to any or all of them with:
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QSpinBox, QLineEdit, QComboBox, QLabel
import sys
class SimpleApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("PySide6 Simple App")
self.setGeometry(100, 100, 300, 200)
self.spin_box = QSpinBox()
self.line_edit = QLineEdit()
self.combo_box = QComboBox()
self.label = QLabel("Choose and enter values:")
self.spin_box.setRange(0, 100)
self.combo_box.addItems(["Option 1", "Option 2", "Option 3"])
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.spin_box)
layout.addWidget(self.line_edit)
layout.addWidget(self.combo_box)
self.setLayout(layout)
# Connect signals to slots
self.spin_box.valueChanged.connect(self.app_modify)
self.line_edit.textChanged.connect(self.app_modify)
self.combo_box.currentTextChanged.connect(self.app_modify)
def app_modify(self, *args):
print(args)
spin_value = self.spin_box.value()
line_text = self.line_edit.text()
combo_text = self.combo_box.currentText()
self.label.setText(f"SpinBox: {spin_value}, LineEdit: '{line_text}', ComboBox: {combo_text}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SimpleApp()
window.show()
sys.exit(app.exec())
hi @Michal_Plichta good morning.
Let me give you a little more context on what I want to do.
What I want to do is similar to what Microsoft Word does ,for example ,if you open a new document and you don’t write anything in it and you press close ,it closes ,if you write something and you want to close the document ,the program asks if you want to save the information.
The solution that you are proposing is valid, but if the application has dozens of widgets, is this the most efficient way to do it?
There is a method called isWindowModified, but I do not know how to implement it.
Translated with DeepL.com (free version)
Ok got it!.
I think you have to one by one and check state of flag app_modified
in closeEvent()
, which is called when user close appliaction, like:
import sys
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QSpinBox, QLineEdit, QComboBox, QLabel, QMessageBox
class SimpleApp(QWidget):
def __init__(self):
super().__init__()
self.app_modified = False
self.setWindowTitle("PySide6 Simple App")
self.setGeometry(100, 100, 300, 200)
self.spin_box = QSpinBox()
self.line_edit = QLineEdit()
self.combo_box = QComboBox()
self.label = QLabel("Choose and enter values:")
self.spin_box.setRange(0, 100)
self.combo_box.addItems(["Option 1", "Option 2", "Option 3"])
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.spin_box)
layout.addWidget(self.line_edit)
layout.addWidget(self.combo_box)
self.setLayout(layout)
# Connect signals to slots
self.spin_box.valueChanged.connect(self.app_modify)
self.line_edit.textChanged.connect(self.app_modify)
self.combo_box.currentTextChanged.connect(self.app_modify)
def app_modify(self, *args):
print(args)
self.app_modified = True
spin_value = self.spin_box.value()
line_text = self.line_edit.text()
combo_text = self.combo_box.currentText()
self.label.setText(f"SpinBox: {spin_value}, LineEdit: '{line_text}', ComboBox: {combo_text}")
def closeEvent(self, event):
if self.app_modified:
reply = QMessageBox.question(self, "Confirm Exit", "Are you sure you want to close the application?")
if reply == QMessageBox.StandardButton.Yes:
event.accept()
else:
event.ignore()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SimpleApp()
window.show()
sys.exit(app.exec())
Sorry I didn’t noticed your question regarding isWindowModified()
As far I understood, this just fancy wrapper for regular bool flag. Note: self.setWindowTitle("PySide6 Simple App [*]")
give user feedback that app was modified, see example:
import sys
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QSpinBox, QLineEdit, QComboBox, QLabel, QMessageBox
class SimpleApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("PySide6 Simple App")
self.setGeometry(100, 100, 300, 200)
self.spin_box = QSpinBox()
self.line_edit = QLineEdit()
self.combo_box = QComboBox()
self.label = QLabel("Choose and enter values:")
self.spin_box.setRange(0, 100)
self.combo_box.addItems(["Option 1", "Option 2", "Option 3"])
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.spin_box)
layout.addWidget(self.line_edit)
layout.addWidget(self.combo_box)
self.setLayout(layout)
self.spin_box.valueChanged.connect(self.app_modify)
self.line_edit.textChanged.connect(self.app_modify)
self.combo_box.currentTextChanged.connect(self.app_modify)
def app_modify(self, *args):
print(args)
self.setWindowModified(True)
self.setWindowTitle("PySide6 Simple App [*]")
spin_value = self.spin_box.value()
line_text = self.line_edit.text()
combo_text = self.combo_box.currentText()
self.label.setText(f"SpinBox: {spin_value}, LineEdit: '{line_text}', ComboBox: {combo_text}")
def closeEvent(self, event):
if self.isWindowModified():
reply = QMessageBox.question(self, "Confirm Exit", "Unsaved changes detected. Are you sure you want to close the application?")
if reply == QMessageBox.StandardButton.Yes:
event.accept()
else:
event.ignore()
else:
event.accept()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = SimpleApp()
window.show()
sys.exit(app.exec())
Hello @Michal_, thank you very much for your help