aboutsummaryrefslogtreecommitdiffstats
path: root/examples/widgets/tutorials
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets/tutorials')
-rw-r--r--examples/widgets/tutorials/addressbook/part1.py5
-rw-r--r--examples/widgets/tutorials/addressbook/part2.py13
-rw-r--r--examples/widgets/tutorials/addressbook/part3.py15
-rw-r--r--examples/widgets/tutorials/addressbook/part4.py32
-rw-r--r--examples/widgets/tutorials/addressbook/part5.py36
-rw-r--r--examples/widgets/tutorials/addressbook/part6.py50
-rw-r--r--examples/widgets/tutorials/addressbook/part7.py57
-rw-r--r--examples/widgets/tutorials/cannon/t10.py8
-rw-r--r--examples/widgets/tutorials/cannon/t11.py8
-rw-r--r--examples/widgets/tutorials/cannon/t12.py8
-rw-r--r--examples/widgets/tutorials/cannon/t13.py10
-rw-r--r--examples/widgets/tutorials/cannon/t14.py17
-rw-r--r--examples/widgets/tutorials/cannon/t2.py3
-rw-r--r--examples/widgets/tutorials/cannon/t4.py2
-rw-r--r--examples/widgets/tutorials/cannon/t5.py2
-rw-r--r--examples/widgets/tutorials/cannon/t6.py2
-rw-r--r--examples/widgets/tutorials/cannon/t7.py2
-rw-r--r--examples/widgets/tutorials/cannon/t8.py8
-rw-r--r--examples/widgets/tutorials/cannon/t9.py8
-rw-r--r--examples/widgets/tutorials/modelview/1_readonly.py38
-rw-r--r--examples/widgets/tutorials/modelview/2_formatting.py65
-rw-r--r--examples/widgets/tutorials/modelview/3_changingmodel.py53
-rw-r--r--examples/widgets/tutorials/modelview/4_headers.py43
-rw-r--r--examples/widgets/tutorials/modelview/5_edit.py73
-rw-r--r--examples/widgets/tutorials/modelview/6_treeview.py42
-rw-r--r--examples/widgets/tutorials/modelview/7_selections.py71
-rw-r--r--examples/widgets/tutorials/modelview/doc/modelview.rst4
-rw-r--r--examples/widgets/tutorials/modelview/modelview.pyproject9
28 files changed, 550 insertions, 134 deletions
diff --git a/examples/widgets/tutorials/addressbook/part1.py b/examples/widgets/tutorials/addressbook/part1.py
index e26206d8f..648ddea46 100644
--- a/examples/widgets/tutorials/addressbook/part1.py
+++ b/examples/widgets/tutorials/addressbook/part1.py
@@ -5,9 +5,8 @@
import sys
from PySide6.QtCore import Qt
-from PySide6.QtWidgets import (QApplication, QGridLayout,
- QLabel, QGridLayout, QLineEdit, QTextEdit,
- QWidget)
+from PySide6.QtWidgets import (QApplication, QGridLayout, QLabel, QLineEdit,
+ QTextEdit, QWidget)
class AddressBook(QWidget):
diff --git a/examples/widgets/tutorials/addressbook/part2.py b/examples/widgets/tutorials/addressbook/part2.py
index ccc6139ab..3c0eb451d 100644
--- a/examples/widgets/tutorials/addressbook/part2.py
+++ b/examples/widgets/tutorials/addressbook/part2.py
@@ -4,9 +4,9 @@
import sys
-from PySide6.QtCore import Qt, Signal, Slot
-from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
- QHBoxLayout, QLabel, QLineEdit,
+from PySide6.QtCore import Qt
+from PySide6.QtWidgets import (QApplication, QGridLayout,
+ QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
@@ -102,17 +102,16 @@ class AddressBook(QWidget):
address = self._address_text.toPlainText()
if name == "" or address == "":
- QMessageBox.information(self, "Empty Field",
- "Please enter a name and address.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
return
if name not in self.contacts:
self.contacts[name] = address
QMessageBox.information(self, "Add Successful",
- f'"{name}" has been added to your address book.')
+ f'"{name}" has been added to your address book.')
else:
QMessageBox.information(self, "Add Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
if not self.contacts:
diff --git a/examples/widgets/tutorials/addressbook/part3.py b/examples/widgets/tutorials/addressbook/part3.py
index 5365c1ae0..611796f5e 100644
--- a/examples/widgets/tutorials/addressbook/part3.py
+++ b/examples/widgets/tutorials/addressbook/part3.py
@@ -4,8 +4,8 @@
import sys
-from PySide6.QtCore import Qt, Signal, Slot
-from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtWidgets import (QApplication, QGridLayout,
QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
@@ -110,22 +110,22 @@ class AddressBook(QWidget):
self._submit_button.show()
self._cancel_button.show()
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
if name == "" or address == "":
- QMessageBox.information(self, "Empty Field",
- "Please enter a name and address.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
return
if name not in self.contacts:
self.contacts[name] = address
QMessageBox.information(self, "Add Successful",
- f'"{name}" has been added to your address book.')
+ f'"{name}" has been added to your address book.')
else:
QMessageBox.information(self, "Add Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
if not self.contacts:
@@ -143,6 +143,7 @@ class AddressBook(QWidget):
self._submit_button.hide()
self._cancel_button.hide()
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
@@ -162,6 +163,7 @@ class AddressBook(QWidget):
self._submit_button.hide()
self._cancel_button.hide()
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -179,6 +181,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/addressbook/part4.py b/examples/widgets/tutorials/addressbook/part4.py
index 0b1edb054..95f31d46c 100644
--- a/examples/widgets/tutorials/addressbook/part4.py
+++ b/examples/widgets/tutorials/addressbook/part4.py
@@ -4,8 +4,8 @@
import sys
-from PySide6.QtCore import Qt, Signal, Slot
-from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtWidgets import (QApplication, QGridLayout,
QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
QVBoxLayout, QWidget)
@@ -105,6 +105,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -114,72 +115,76 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
if name == "" or address == "":
- QMessageBox.information(self, "Empty Field",
- "Please enter a name and address.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
return
if self._current_mode == self.AddingMode:
if name not in self.contacts:
self.contacts[name] = address
QMessageBox.information(self, "Add Successful",
- f'"{name}" has been added to your address book.')
+ f'"{name}" has been added to your address book.')
else:
QMessageBox.information(self, "Add Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._current_mode == self.EditingMode:
if self._old_name != name:
if name not in self.contacts:
QMessageBox.information(self, "Edit Successful",
- f'"{self.oldName}" has been edited in your address book.')
+ f'"{self.oldName}" has been edited in your '
+ 'address book.')
del self.contacts[self._old_name]
self.contacts[name] = address
else:
QMessageBox.information(self, "Edit Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._old_address != address:
QMessageBox.information(self, "Edit Successful",
- f'"{name}" has been edited in your address book.')
+ f'"{name}" has been edited in your address book.')
self.contacts[name] = address
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
- address = self._address_text.toPlainText()
if name in self.contacts:
button = QMessageBox.question(self, "Confirm Remove",
- f'Are you sure you want to remove "{name}"?',
- QMessageBox.Yes | QMessageBox.No)
+ f'Are you sure you want to remove "{name}"?',
+ QMessageBox.Yes | QMessageBox.No)
if button == QMessageBox.Yes:
self.previous()
del self.contacts[name]
QMessageBox.information(self, "Remove Successful",
- f'"{name}" has been removed from your address book.')
+ f'"{name}" has been removed from your address book.')
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -197,6 +202,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
diff --git a/examples/widgets/tutorials/addressbook/part5.py b/examples/widgets/tutorials/addressbook/part5.py
index 48404c95d..1e9c05862 100644
--- a/examples/widgets/tutorials/addressbook/part5.py
+++ b/examples/widgets/tutorials/addressbook/part5.py
@@ -2,10 +2,9 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-import pickle
import sys
-from PySide6.QtCore import Qt, Signal, Slot
+from PySide6.QtCore import Qt, Slot
from PySide6.QtWidgets import (QApplication, QDialog, QGridLayout,
QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
@@ -112,6 +111,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -121,72 +121,76 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
if name == "" or address == "":
- QMessageBox.information(self, "Empty Field",
- "Please enter a name and address.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
return
if self._current_mode == self.AddingMode:
if name not in self.contacts:
self.contacts[name] = address
QMessageBox.information(self, "Add Successful",
- f'"{name}" has been added to your address book.')
+ f'"{name}" has been added to your address book.')
else:
QMessageBox.information(self, "Add Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._current_mode == self.EditingMode:
if self._old_name != name:
if name not in self.contacts:
QMessageBox.information(self, "Edit Successful",
- f'"{self.oldName}" has been edited in your address book.')
+ f'"{self.oldName}" has been edited in your '
+ 'address book.')
del self.contacts[self._old_name]
self.contacts[name] = address
else:
QMessageBox.information(self, "Edit Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._old_address != address:
QMessageBox.information(self, "Edit Successful",
- f'"{name}" has been edited in your address book.')
+ f'"{name}" has been edited in your address book.')
self.contacts[name] = address
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
- address = self._address_text.toPlainText()
if name in self.contacts:
button = QMessageBox.question(self, "Confirm Remove",
- f'Are you sure you want to remove "{name}"?',
- QMessageBox.Yes | QMessageBox.No)
+ f'Are you sure you want to remove "{name}"?',
+ QMessageBox.Yes | QMessageBox.No)
if button == QMessageBox.Yes:
self.previous()
del self.contacts[name]
QMessageBox.information(self, "Remove Successful",
- f'"{name}" has been removed from your address book.')
+ f'"{name}" has been removed from your address book.')
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -204,6 +208,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
@@ -237,7 +242,7 @@ class AddressBook(QWidget):
self._address_text.setText(self.contacts[contact_name])
else:
QMessageBox.information(self, "Contact Not Found",
- f'Sorry, "{contact_name}" is not in your address book.')
+ f'Sorry, "{contact_name}" is not in your address book.')
return
self.update_interface(self.NavigationMode)
@@ -305,8 +310,7 @@ class FindDialog(QDialog):
text = self._line_edit.text()
if not text:
- QMessageBox.information(self, "Empty Field",
- "Please enter a name.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name.")
return
else:
self._find_text = text
diff --git a/examples/widgets/tutorials/addressbook/part6.py b/examples/widgets/tutorials/addressbook/part6.py
index 9070a34da..d11298fb9 100644
--- a/examples/widgets/tutorials/addressbook/part6.py
+++ b/examples/widgets/tutorials/addressbook/part6.py
@@ -5,7 +5,7 @@
import pickle
import sys
-from PySide6.QtCore import QFile, QIODevice, QTextStream, Qt, Signal, Slot
+from PySide6.QtCore import Qt, Slot
from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
QGridLayout, QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
@@ -122,6 +122,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -131,72 +132,76 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
if name == "" or address == "":
- QMessageBox.information(self, "Empty Field",
- "Please enter a name and address.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
return
if self._current_mode == self.AddingMode:
if name not in self.contacts:
self.contacts[name] = address
QMessageBox.information(self, "Add Successful",
- f'"{name}" has been added to your address book.')
+ f'"{name}" has been added to your address book.')
else:
QMessageBox.information(self, "Add Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._current_mode == self.EditingMode:
if self._old_name != name:
if name not in self.contacts:
QMessageBox.information(self, "Edit Successful",
- f'"{self.oldName}" has been edited in your address book.')
+ f'"{self.oldName}" has been edited in your '
+ 'address book.')
del self.contacts[self._old_name]
self.contacts[name] = address
else:
QMessageBox.information(self, "Edit Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._old_address != address:
QMessageBox.information(self, "Edit Successful",
- f'"{name}" has been edited in your address book.')
+ f'"{name}" has been edited in your address book.')
self.contacts[name] = address
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
- address = self._address_text.toPlainText()
if name in self.contacts:
button = QMessageBox.question(self, "Confirm Remove",
- f'Are you sure you want to remove "{name}"?',
- QMessageBox.Yes | QMessageBox.No)
+ f'Are you sure you want to remove "{name}"?',
+ QMessageBox.Yes | QMessageBox.No)
if button == QMessageBox.Yes:
self.previous()
del self.contacts[name]
QMessageBox.information(self, "Remove Successful",
- f'"{name}" has been removed from your address book.')
+ f'"{name}" has been removed from your address book.')
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -214,6 +219,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
@@ -247,7 +253,7 @@ class AddressBook(QWidget):
self._address_text.setText(self.contacts[contact_name])
else:
QMessageBox.information(self, "Contact Not Found",
- f'Sorry, "{contact_name}" is not in your address book.')
+ f'Sorry, "{contact_name}" is not in your address book.')
return
self.update_interface(self.NavigationMode)
@@ -297,8 +303,8 @@ class AddressBook(QWidget):
def save_to_file(self):
fileName, _ = QFileDialog.getSaveFileName(self,
- "Save Address Book", '',
- "Address Book (*.abk);;All Files (*)")
+ "Save Address Book", '',
+ "Address Book (*.abk);;All Files (*)")
if not fileName:
return
@@ -307,7 +313,7 @@ class AddressBook(QWidget):
out_file = open(str(fileName), 'wb')
except IOError:
QMessageBox.information(self, "Unable to open file",
- f'There was an error opening "{fileName}"')
+ f'There was an error opening "{fileName}"')
return
pickle.dump(self.contacts, out_file)
@@ -315,8 +321,8 @@ class AddressBook(QWidget):
def load_from_file(self):
fileName, _ = QFileDialog.getOpenFileName(self,
- "Open Address Book", '',
- "Address Book (*.abk);;All Files (*)")
+ "Open Address Book", '',
+ "Address Book (*.abk);;All Files (*)")
if not fileName:
return
@@ -325,7 +331,7 @@ class AddressBook(QWidget):
in_file = open(str(fileName), 'rb')
except IOError:
QMessageBox.information(self, "Unable to open file",
- f'There was an error opening "{fileName}"')
+ f'There was an error opening "{fileName}"')
return
self.contacts = pickle.load(in_file)
@@ -333,8 +339,7 @@ class AddressBook(QWidget):
if len(self.contacts) == 0:
QMessageBox.information(self, "No contacts in file",
- "The file you are attempting to open contains no "
- "contacts.")
+ "The file you are attempting to open contains no contacts.")
else:
for name, address in self.contacts:
self._name_line.setText(name)
@@ -368,8 +373,7 @@ class FindDialog(QDialog):
text = self._line_edit.text()
if not text:
- QMessageBox.information(self, "Empty Field",
- "Please enter a name.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name.")
return
self._find_text = text
diff --git a/examples/widgets/tutorials/addressbook/part7.py b/examples/widgets/tutorials/addressbook/part7.py
index 2fc7a8d1c..3829c003d 100644
--- a/examples/widgets/tutorials/addressbook/part7.py
+++ b/examples/widgets/tutorials/addressbook/part7.py
@@ -5,7 +5,7 @@
import pickle
import sys
-from PySide6.QtCore import QFile, QIODevice, QTextStream, Qt, Signal, Slot
+from PySide6.QtCore import QFile, QIODevice, QTextStream, Qt, Slot
from PySide6.QtWidgets import (QApplication, QDialog, QFileDialog,
QGridLayout, QHBoxLayout, QLabel, QLineEdit,
QMessageBox, QPushButton, QTextEdit,
@@ -128,6 +128,7 @@ class AddressBook(QWidget):
self.setLayout(main_layout)
self.setWindowTitle("Simple Address Book")
+ @Slot()
def add_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
@@ -137,72 +138,76 @@ class AddressBook(QWidget):
self.update_interface(self.AddingMode)
+ @Slot()
def edit_contact(self):
self._old_name = self._name_line.text()
self._old_address = self._address_text.toPlainText()
self.update_interface(self.EditingMode)
+ @Slot()
def submit_contact(self):
name = self._name_line.text()
address = self._address_text.toPlainText()
if name == "" or address == "":
- QMessageBox.information(self, "Empty Field",
- "Please enter a name and address.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name and address.")
return
if self._current_mode == self.AddingMode:
if name not in self.contacts:
self.contacts[name] = address
QMessageBox.information(self, "Add Successful",
- f'"{name}" has been added to your address book.')
+ f'"{name}" has been added to your address book.')
else:
QMessageBox.information(self, "Add Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._current_mode == self.EditingMode:
if self._old_name != name:
if name not in self.contacts:
QMessageBox.information(self, "Edit Successful",
- f'"{self.oldName}" has been edited in your address book.')
+ f'"{self.oldName}" has been edited in your '
+ 'address book.')
del self.contacts[self._old_name]
self.contacts[name] = address
else:
QMessageBox.information(self, "Edit Unsuccessful",
- f'Sorry, "{name}" is already in your address book.')
+ f'Sorry, "{name}" is already in your address book.')
return
elif self._old_address != address:
QMessageBox.information(self, "Edit Successful",
- f'"{name}" has been edited in your address book.')
+ f'"{name}" has been edited in your address book.')
self.contacts[name] = address
self.update_interface(self.NavigationMode)
+ @Slot()
def cancel(self):
self._name_line.setText(self._old_name)
self._address_text.setText(self._old_address)
self.update_interface(self.NavigationMode)
+ @Slot()
def remove_contact(self):
name = self._name_line.text()
- address = self._address_text.toPlainText()
if name in self.contacts:
button = QMessageBox.question(self, "Confirm Remove",
- f'Are you sure you want to remove "{name}"?',
- QMessageBox.Yes | QMessageBox.No)
+ f'Are you sure you want to remove "{name}"?',
+ QMessageBox.Yes | QMessageBox.No)
if button == QMessageBox.Yes:
self.previous()
del self.contacts[name]
QMessageBox.information(self, "Remove Successful",
- f'"{name}" has been removed from your address book.')
+ f'"{name}" has been removed from your address book.')
self.update_interface(self.NavigationMode)
+ @Slot()
def next(self):
name = self._name_line.text()
it = iter(self.contacts)
@@ -220,6 +225,7 @@ class AddressBook(QWidget):
self._name_line.setText(next_name)
self._address_text.setText(next_address)
+ @Slot()
def previous(self):
name = self._name_line.text()
@@ -253,7 +259,7 @@ class AddressBook(QWidget):
self._address_text.setText(self.contacts[contact_name])
else:
QMessageBox.information(self, "Contact Not Found",
- f'Sorry, "{contact_name}" is not in your address book.')
+ f'Sorry, "{contact_name}" is not in your address book.')
return
self.update_interface(self.NavigationMode)
@@ -306,8 +312,8 @@ class AddressBook(QWidget):
def save_to_file(self):
fileName, _ = QFileDialog.getSaveFileName(self,
- "Save Address Book", '',
- "Address Book (*.abk);;All Files (*)")
+ "Save Address Book", '',
+ "Address Book (*.abk);;All Files (*)")
if not fileName:
return
@@ -316,7 +322,7 @@ class AddressBook(QWidget):
out_file = open(str(fileName), 'wb')
except IOError:
QMessageBox.information(self, "Unable to open file",
- f'There was an error opening "{fileName}"')
+ f'There was an error opening "{fileName}"')
return
pickle.dump(self.contacts, out_file)
@@ -324,8 +330,8 @@ class AddressBook(QWidget):
def load_from_file(self):
fileName, _ = QFileDialog.getOpenFileName(self,
- "Open Address Book", '',
- "Address Book (*.abk);;All Files (*)")
+ "Open Address Book", '',
+ "Address Book (*.abk);;All Files (*)")
if not fileName:
return
@@ -334,7 +340,7 @@ class AddressBook(QWidget):
in_file = open(str(fileName), 'rb')
except IOError:
QMessageBox.information(self, "Unable to open file",
- f'There was an error opening "{fileName}"')
+ f'There was an error opening "{fileName}"')
return
self.contacts = pickle.load(in_file)
@@ -342,8 +348,7 @@ class AddressBook(QWidget):
if len(self.contacts) == 0:
QMessageBox.information(self, "No contacts in file",
- "The file you are attempting to open contains no "
- "contacts.")
+ "The file you are attempting to open contains no contacts.")
else:
for name, address in self.contacts:
self._name_line.setText(name)
@@ -365,7 +370,7 @@ class AddressBook(QWidget):
last_name = ''
file_name = QFileDialog.getSaveFileName(self, "Export Contact",
- '', "vCard Files (*.vcf);;All Files (*)")[0]
+ '', "vCard Files (*.vcf);;All Files (*)")[0]
if not file_name:
return
@@ -373,8 +378,7 @@ class AddressBook(QWidget):
out_file = QFile(file_name)
if not out_file.open(QIODevice.WriteOnly):
- QMessageBox.information(self, "Unable to open file",
- out_file.errorString())
+ QMessageBox.information(self, "Unable to open file", out_file.errorString())
return
out_s = QTextStream(out_file)
@@ -392,7 +396,7 @@ class AddressBook(QWidget):
out_s << 'END:VCARD' << '\n'
QMessageBox.information(self, "Export Successful",
- f'"{name}" has been exported as a vCard.')
+ f'"{name}" has been exported as a vCard.')
class FindDialog(QDialog):
@@ -420,8 +424,7 @@ class FindDialog(QDialog):
text = self._line_edit.text()
if not text:
- QMessageBox.information(self, "Empty Field",
- "Please enter a name.")
+ QMessageBox.information(self, "Empty Field", "Please enter a name.")
return
self._find_text = text
diff --git a/examples/widgets/tutorials/cannon/t10.py b/examples/widgets/tutorials/cannon/t10.py
index db080f050..8649bb562 100644
--- a/examples/widgets/tutorials/cannon/t10.py
+++ b/examples/widgets/tutorials/cannon/t10.py
@@ -6,7 +6,7 @@
import sys
-from PySide6.QtCore import QRect, Qt, Signal, Slot
+from PySide6.QtCore import QRect, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette
from PySide6.QtWidgets import (QApplication, QGridLayout, QLCDNumber,
QPushButton, QSlider, QVBoxLayout, QWidget)
@@ -43,8 +43,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning(f"LCDRange::setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -113,7 +113,7 @@ class MyWidget(QWidget):
quit = QPushButton("&Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange()
angle.set_range(5, 70)
diff --git a/examples/widgets/tutorials/cannon/t11.py b/examples/widgets/tutorials/cannon/t11.py
index c7a4ffbd4..fbfd2481d 100644
--- a/examples/widgets/tutorials/cannon/t11.py
+++ b/examples/widgets/tutorials/cannon/t11.py
@@ -7,7 +7,7 @@
import sys
import math
-from PySide6.QtCore import QPoint, QRect, QTimer, Qt, Signal, Slot
+from PySide6.QtCore import QPoint, QRect, QTimer, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette, QRegion
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout,
QLCDNumber, QPushButton, QSlider,
@@ -45,8 +45,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning(f"LCDRange::setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -175,7 +175,7 @@ class MyWidget(QWidget):
quit = QPushButton("&Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange()
angle.set_range(5, 70)
diff --git a/examples/widgets/tutorials/cannon/t12.py b/examples/widgets/tutorials/cannon/t12.py
index 3887bbf2e..749c24684 100644
--- a/examples/widgets/tutorials/cannon/t12.py
+++ b/examples/widgets/tutorials/cannon/t12.py
@@ -8,7 +8,7 @@ import sys
import math
import random
-from PySide6.QtCore import QPoint, QRect, QTime, QTimer, Qt, Signal, Slot
+from PySide6.QtCore import QPoint, QRect, QTime, QTimer, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette, QRegion
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout,
QLabel, QLCDNumber, QPushButton, QSlider,
@@ -62,8 +62,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning(f"LCDRange::setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -226,7 +226,7 @@ class MyWidget(QWidget):
quit = QPushButton("&Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange("ANGLE")
angle.set_range(5, 70)
diff --git a/examples/widgets/tutorials/cannon/t13.py b/examples/widgets/tutorials/cannon/t13.py
index ddd5341da..f9a771d15 100644
--- a/examples/widgets/tutorials/cannon/t13.py
+++ b/examples/widgets/tutorials/cannon/t13.py
@@ -8,8 +8,8 @@ import sys
import math
import random
-from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, Qt, SIGNAL, SLOT,
- Signal, Slot)
+from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, Qt,
+ Signal, Slot, qWarning)
from PySide6.QtGui import QColor, QFont, QPainter, QPalette, QRegion
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout, QLabel,
QLCDNumber, QPushButton, QSizePolicy, QSlider,
@@ -64,8 +64,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning(f"LCDRange::setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -259,7 +259,7 @@ class GameBoard(QWidget):
quit = QPushButton("&Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange("ANGLE")
angle.set_range(5, 70)
diff --git a/examples/widgets/tutorials/cannon/t14.py b/examples/widgets/tutorials/cannon/t14.py
index aa0f8876b..3c94408f3 100644
--- a/examples/widgets/tutorials/cannon/t14.py
+++ b/examples/widgets/tutorials/cannon/t14.py
@@ -8,10 +8,10 @@ import sys
import math
import random
-from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, QSize, Qt, SIGNAL,
- SLOT, Signal, Slot)
+from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, QSize, Qt,
+ Signal, Slot, qWarning)
from PySide6.QtGui import (QColor, QFont, QKeySequence, QPainter, QPalette,
- QShortcut, QRegion)
+ QShortcut, QRegion, QTransform)
from PySide6.QtWidgets import (QApplication, QFrame, QGridLayout, QHBoxLayout,
QLabel, QLCDNumber, QPushButton, QSizePolicy,
QSlider, QVBoxLayout, QWidget)
@@ -65,8 +65,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning(f"LCDRange::setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -174,7 +174,8 @@ class CannonField(QWidget):
self._auto_shoot_timer.stop()
self.hit.emit()
self.can_shoot.emit(True)
- elif shot_r.x() > self.width() or shot_r.y() > self.height() or shot_r.intersects(self.barrier_rect()):
+ elif (shot_r.x() > self.width() or shot_r.y() > self.height()
+ or shot_r.intersects(self.barrier_rect())):
self._auto_shoot_timer.stop()
self.missed.emit()
self.can_shoot.emit(True)
@@ -301,7 +302,7 @@ class GameBoard(QWidget):
quit = QPushButton("&Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange("ANGLE")
angle.set_range(5, 70)
@@ -341,7 +342,7 @@ class GameBoard(QWidget):
QShortcut(QKeySequence(Qt.Key_Enter), self, self.fire)
QShortcut(QKeySequence(Qt.Key_Return), self, self.fire)
- QShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q), self, self.close)
+ QShortcut(QKeySequence(Qt.CTRL | Qt.Key_Q), self, self.close)
top_layout = QHBoxLayout()
top_layout.addWidget(shoot)
diff --git a/examples/widgets/tutorials/cannon/t2.py b/examples/widgets/tutorials/cannon/t2.py
index 57326ac37..d3adba396 100644
--- a/examples/widgets/tutorials/cannon/t2.py
+++ b/examples/widgets/tutorials/cannon/t2.py
@@ -6,9 +6,8 @@
import sys
-from PySide6.QtCore import (QPoint, QRect, QTime, QTimer, Qt)
from PySide6.QtGui import QFont
-from PySide6.QtWidgets import (QApplication, QPushButton)
+from PySide6.QtWidgets import QApplication, QPushButton
if __name__ == '__main__':
diff --git a/examples/widgets/tutorials/cannon/t4.py b/examples/widgets/tutorials/cannon/t4.py
index ba0ebc41b..37a2dc9dd 100644
--- a/examples/widgets/tutorials/cannon/t4.py
+++ b/examples/widgets/tutorials/cannon/t4.py
@@ -20,7 +20,7 @@ class MyWidget(QWidget):
self.quit.setGeometry(62, 40, 75, 30)
self.quit.setFont(QFont("Times", 18, QFont.Bold))
- self.quit.clicked.connect(qApp.quit)
+ self.quit.clicked.connect(qApp.quit) # noqa: F821
if __name__ == '__main__':
diff --git a/examples/widgets/tutorials/cannon/t5.py b/examples/widgets/tutorials/cannon/t5.py
index 42faeed01..ed5d085f8 100644
--- a/examples/widgets/tutorials/cannon/t5.py
+++ b/examples/widgets/tutorials/cannon/t5.py
@@ -25,7 +25,7 @@ class MyWidget(QWidget):
slider.setRange(0, 99)
slider.setValue(0)
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
slider.valueChanged.connect(lcd.display)
layout = QVBoxLayout(self)
diff --git a/examples/widgets/tutorials/cannon/t6.py b/examples/widgets/tutorials/cannon/t6.py
index 1cc2906f2..ea2e044e6 100644
--- a/examples/widgets/tutorials/cannon/t6.py
+++ b/examples/widgets/tutorials/cannon/t6.py
@@ -33,7 +33,7 @@ class MyWidget(QWidget):
quit = QPushButton("Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
layout = QVBoxLayout(self)
layout.addWidget(quit)
diff --git a/examples/widgets/tutorials/cannon/t7.py b/examples/widgets/tutorials/cannon/t7.py
index 51128e6c7..1175107b8 100644
--- a/examples/widgets/tutorials/cannon/t7.py
+++ b/examples/widgets/tutorials/cannon/t7.py
@@ -46,7 +46,7 @@ class MyWidget(QWidget):
quit = QPushButton("Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
previous_range = None
diff --git a/examples/widgets/tutorials/cannon/t8.py b/examples/widgets/tutorials/cannon/t8.py
index c887a36a6..9bb5516b8 100644
--- a/examples/widgets/tutorials/cannon/t8.py
+++ b/examples/widgets/tutorials/cannon/t8.py
@@ -6,7 +6,7 @@
import sys
-from PySide6.QtCore import Signal, Slot, Qt
+from PySide6.QtCore import Signal, Slot, Qt, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette
from PySide6.QtWidgets import (QApplication, QGridLayout, QLCDNumber,
QPushButton, QSlider, QVBoxLayout, QWidget)
@@ -43,8 +43,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning("LCDRange.setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -88,7 +88,7 @@ class MyWidget(QWidget):
quit = QPushButton("Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange()
angle.set_range(5, 70)
diff --git a/examples/widgets/tutorials/cannon/t9.py b/examples/widgets/tutorials/cannon/t9.py
index 2526d1573..7cdda4e7b 100644
--- a/examples/widgets/tutorials/cannon/t9.py
+++ b/examples/widgets/tutorials/cannon/t9.py
@@ -6,7 +6,7 @@
import sys
-from PySide6.QtCore import QRect, Qt, Signal, Slot
+from PySide6.QtCore import QRect, Qt, Signal, Slot, qWarning
from PySide6.QtGui import QColor, QFont, QPainter, QPalette
from PySide6.QtWidgets import (QApplication, QGridLayout, QLCDNumber,
QPushButton, QSlider, QVBoxLayout, QWidget)
@@ -43,8 +43,8 @@ class LCDRange(QWidget):
def set_range(self, minValue, maxValue):
if minValue < 0 or maxValue > 99 or minValue > maxValue:
qWarning(f"LCDRange::setRange({minValue}, {maxValue})\n"
- "\tRange must be 0..99\n"
- "\tand minValue must not be greater than maxValue")
+ "\tRange must be 0..99\n"
+ "\tand minValue must not be greater than maxValue")
return
self.slider.setRange(minValue, maxValue)
@@ -94,7 +94,7 @@ class MyWidget(QWidget):
quit = QPushButton("Quit")
quit.setFont(QFont("Times", 18, QFont.Bold))
- quit.clicked.connect(qApp.quit)
+ quit.clicked.connect(qApp.quit) # noqa: F821
angle = LCDRange()
angle.set_range(5, 70)
diff --git a/examples/widgets/tutorials/modelview/1_readonly.py b/examples/widgets/tutorials/modelview/1_readonly.py
new file mode 100644
index 000000000..9dc923260
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/1_readonly.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/1_readonly example from Qt v6.x"""
+
+
+#! [1]
+class MyModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ row = index.row() + 1
+ column = index.column() + 1
+ return f"Row{row}, Column{column}"
+ return None
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/2_formatting.py b/examples/widgets/tutorials/modelview/2_formatting.py
new file mode 100644
index 000000000..f39ec462c
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/2_formatting.py
@@ -0,0 +1,65 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtGui import QBrush, QFont
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/2_formatting example from Qt v6.x"""
+
+
+class MyModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+#! [1]
+ def data(self, index, role=Qt.DisplayRole):
+ row = index.row()
+ col = index.column()
+ # generate a log message when this method gets called
+ print(f"row {row}, col{col}, role {role}")
+
+ if role == Qt.DisplayRole:
+ if row == 0 and col == 1:
+ return "<--left"
+ if row == 1 and col == 1:
+ return "right-->"
+ return f"Row{row}, Column{col + 1}"
+
+ elif role == Qt.FontRole:
+ if row == 0 and col == 0: # change font only for cell(0,0)
+ bold_font = QFont()
+ bold_font.setBold(True)
+ return bold_font
+
+ elif role == Qt.BackgroundRole:
+ if row == 1 and col == 2: # change background only for cell(1,2)
+ return QBrush(Qt.red)
+
+ elif role == Qt.TextAlignmentRole:
+ if row == 1 and col == 1: # change text alignment only for cell(1,1)
+ return Qt.AlignRight | Qt.AlignVCenter
+
+ elif role == Qt.CheckStateRole:
+ if row == 1 and col == 0: # add a checkbox to cell(1,0)
+ return Qt.Checked
+
+ return None
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/3_changingmodel.py b/examples/widgets/tutorials/modelview/3_changingmodel.py
new file mode 100644
index 000000000..2148ec5d3
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/3_changingmodel.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, QTime, QTimer, Qt, Slot
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/3_changingmodel example from Qt v6.x"""
+
+
+class MyModel(QAbstractTableModel):
+#! [1]
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._timer = QTimer(self)
+ self._timer.setInterval(1000)
+ self._timer.timeout.connect(self.timer_hit)
+ self._timer.start()
+#! [1]
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+#! [2]
+ def data(self, index, role=Qt.DisplayRole):
+ row = index.row()
+ col = index.column()
+ if role == Qt.DisplayRole and row == 0 and col == 0:
+ return QTime.currentTime().toString()
+ return None
+#! [2]
+
+#! [3]
+ @Slot()
+ def timer_hit(self):
+ # we identify the top left cell
+ top_left = self.createIndex(0, 0)
+ # emit a signal to make the view reread identified data
+ self.dataChanged.emit(top_left, top_left, [Qt.DisplayRole])
+#! [3]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/4_headers.py b/examples/widgets/tutorials/modelview/4_headers.py
new file mode 100644
index 000000000..3feef17bf
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/4_headers.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QAbstractTableModel, Qt
+from PySide6.QtWidgets import QApplication, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/4_headers example from Qt v6.x"""
+
+
+class MyModel(QAbstractTableModel):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ def rowCount(self, parent=None):
+ return 2
+
+ def columnCount(self, parent=None):
+ return 3
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole:
+ row = index.row() + 1
+ column = index.column() + 1
+ return f"Row{row}, Column{column}"
+ return None
+
+#! [1]
+ def headerData(self, section, orientation, role):
+ if role == Qt.DisplayRole and orientation == Qt.Horizontal:
+ return ["first", "second", "third"][section]
+ return None
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ table_view = QTableView()
+ my_model = MyModel()
+ table_view.setModel(my_model)
+ table_view.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/5_edit.py b/examples/widgets/tutorials/modelview/5_edit.py
new file mode 100644
index 000000000..1a4481fc9
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/5_edit.py
@@ -0,0 +1,73 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+from itertools import chain
+
+from PySide6.QtCore import QAbstractTableModel, Qt, Signal, Slot
+from PySide6.QtWidgets import QApplication, QMainWindow, QTableView
+
+"""PySide6 port of the widgets/tutorials/modelview/5_edit example from Qt v6.x"""
+
+
+COLS = 3
+ROWS = 2
+
+
+class MyModel(QAbstractTableModel):
+
+ editCompleted = Signal(str)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._grid_data = [["" for y in range(COLS)] for x in range(ROWS)]
+
+ def rowCount(self, parent=None):
+ return ROWS
+
+ def columnCount(self, parent=None):
+ return COLS
+
+ def data(self, index, role=Qt.DisplayRole):
+ if role == Qt.DisplayRole and self.checkIndex(index):
+ return self._grid_data[index.row()][index.column()]
+ return None
+
+#! [1]
+ def setData(self, index, value, role):
+ if role != Qt.EditRole or not self.checkIndex(index):
+ return False
+ # save value from editor to member m_gridData
+ self._grid_data[index.row()][index.column()] = value
+ # for presentation purposes only: build and emit a joined string
+ result = " ".join(chain(*self._grid_data))
+ self.editCompleted.emit(result)
+ return True
+#! [1]
+
+#! [2]
+ def flags(self, index):
+ return Qt.ItemIsEditable | super().flags(index)
+#! [2]
+
+
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._table_view = QTableView(self)
+ self.setCentralWidget(self._table_view)
+ my_model = MyModel(self)
+ self._table_view.setModel(my_model)
+ # transfer changes to the model to the window title
+ my_model.editCompleted.connect(self.show_window_title)
+
+ @Slot(str)
+ def show_window_title(self, title):
+ self.setWindowTitle(title)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/6_treeview.py b/examples/widgets/tutorials/modelview/6_treeview.py
new file mode 100644
index 000000000..cac3c6d53
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/6_treeview.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtWidgets import QApplication, QMainWindow, QTreeView
+
+"""PySide6 port of the widgets/tutorials/modelview/6_treeview example from Qt v6.x"""
+
+
+#! [1]
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._standard_model = QStandardItemModel(self)
+ self._tree_view = QTreeView(self)
+ self.setCentralWidget(self._tree_view)
+
+ prepared_row = self.prepare_row("first", "second", "third")
+ item = self._standard_model.invisibleRootItem()
+ # adding a row to the invisible root item produces a root element
+ item.appendRow(prepared_row)
+
+ second_row = self.prepare_row("111", "222", "333")
+ # adding a row to an item starts a subtree
+ prepared_row[0].appendRow(second_row)
+
+ self._tree_view.setModel(self._standard_model)
+ self._tree_view.expandAll()
+
+ def prepare_row(self, first, second, third):
+ return [QStandardItem(first), QStandardItem(second),
+ QStandardItem(third)]
+#! [1]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/7_selections.py b/examples/widgets/tutorials/modelview/7_selections.py
new file mode 100644
index 000000000..c879d8f67
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/7_selections.py
@@ -0,0 +1,71 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import sys
+
+from PySide6.QtCore import QItemSelection, Qt, Slot
+from PySide6.QtGui import QStandardItem, QStandardItemModel
+from PySide6.QtWidgets import QApplication, QMainWindow, QTreeView
+
+"""PySide6 port of the widgets/tutorials/modelview/7_selections example from Qt v6.x"""
+
+
+#! [1]
+class MainWindow(QMainWindow):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._standard_model = QStandardItemModel(self)
+ self._tree_view = QTreeView(self)
+ self.setCentralWidget(self._tree_view)
+
+ # defining a couple of items
+ root_node = self._standard_model.invisibleRootItem()
+
+ america_item = QStandardItem("America")
+ mexico_item = QStandardItem("Canada")
+ usa_item = QStandardItem("USA")
+ boston_item = QStandardItem("Boston")
+ europe_item = QStandardItem("Europe")
+ italy_item = QStandardItem("Italy")
+ rome_item = QStandardItem("Rome")
+ verona_item = QStandardItem("Verona")
+
+ # building up the hierarchy
+ root_node.appendRow(america_item)
+ root_node.appendRow(europe_item)
+ america_item.appendRow(mexico_item)
+ america_item.appendRow(usa_item)
+ usa_item.appendRow(boston_item)
+ europe_item.appendRow(italy_item)
+ italy_item.appendRow(rome_item)
+ italy_item.appendRow(verona_item)
+
+ self._tree_view.setModel(self._standard_model)
+ self._tree_view.expandAll()
+
+ # selection changes shall trigger a slot
+ selection_model = self._tree_view.selectionModel()
+ selection_model.selectionChanged.connect(self.selection_changed_slot)
+#! [1]
+
+#! [2]
+ @Slot(QItemSelection, QItemSelection)
+ def selection_changed_slot(self, new_selection, old_selection):
+ # get the text of the selected item
+ index = self._tree_view.selectionModel().currentIndex()
+ selected_text = index.data(Qt.DisplayRole)
+ # find out the hierarchy level of the selected item
+ hierarchy_level = 1
+ seek_root = index
+ while seek_root.parent().isValid():
+ seek_root = seek_root.parent()
+ hierarchy_level += 1
+ self.setWindowTitle(f"{selected_text}, Level {hierarchy_level}")
+#! [2]
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec())
diff --git a/examples/widgets/tutorials/modelview/doc/modelview.rst b/examples/widgets/tutorials/modelview/doc/modelview.rst
new file mode 100644
index 000000000..017f78de1
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/doc/modelview.rst
@@ -0,0 +1,4 @@
+Model View Tutorial Examples
+============================
+
+Example code for the Model View Tutorial.
diff --git a/examples/widgets/tutorials/modelview/modelview.pyproject b/examples/widgets/tutorials/modelview/modelview.pyproject
new file mode 100644
index 000000000..3bbe9d47a
--- /dev/null
+++ b/examples/widgets/tutorials/modelview/modelview.pyproject
@@ -0,0 +1,9 @@
+{
+ "files": ["1_readonly.py",
+ "2_formatting.py",
+ "3_changingmodel.py",
+ "4_headers.py",
+ "5_edit.py",
+ "6_treeview.py",
+ "7_selections.py"]
+}