aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py
diff options
context:
space:
mode:
Diffstat (limited to 'sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py')
-rw-r--r--sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py b/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py
new file mode 100644
index 000000000..d728aee59
--- /dev/null
+++ b/sources/pyside6/doc/tutorials/qmlsqlintegration/sqlDialog.py
@@ -0,0 +1,116 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+import datetime
+import logging
+
+from PySide6.QtCore import Qt, Slot
+from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlRecord, QSqlTableModel
+from PySide6.QtQml import QmlElement
+
+table_name = "Conversations"
+QML_IMPORT_NAME = "ChatModel"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+def createTable():
+ if table_name in QSqlDatabase.database().tables():
+ return
+
+ query = QSqlQuery()
+ if not query.exec_(
+ """
+ CREATE TABLE IF NOT EXISTS 'Conversations' (
+ 'author' TEXT NOT NULL,
+ 'recipient' TEXT NOT NULL,
+ 'timestamp' TEXT NOT NULL,
+ 'message' TEXT NOT NULL,
+ FOREIGN KEY('author') REFERENCES Contacts ( name ),
+ FOREIGN KEY('recipient') REFERENCES Contacts ( name )
+ )
+ """
+ ):
+ logging.error("Failed to query database")
+
+ # This adds the first message from the Bot
+ # and further development is required to make it interactive.
+ query.exec_(
+ """
+ INSERT INTO Conversations VALUES(
+ 'machine', 'Me', '2019-01-07T14:36:06', 'Hello!'
+ )
+ """
+ )
+ logging.info(query)
+
+
+@QmlElement
+class SqlConversationModel(QSqlTableModel):
+ def __init__(self, parent=None):
+ super(SqlConversationModel, self).__init__(parent)
+
+ createTable()
+ self.setTable(table_name)
+ self.setSort(2, Qt.DescendingOrder)
+ self.setEditStrategy(QSqlTableModel.OnManualSubmit)
+ self.recipient = ""
+
+ self.select()
+ logging.debug("Table was loaded successfully.")
+
+ def setRecipient(self, recipient):
+ if recipient == self.recipient:
+ pass
+
+ self.recipient = recipient
+
+ filter_str = (f"(recipient = '{self.recipient}' AND author = 'Me') OR "
+ f"(recipient = 'Me' AND author='{self.recipient}')")
+ self.setFilter(filter_str)
+ self.select()
+
+ def data(self, index, role):
+ if role < Qt.UserRole:
+ return QSqlTableModel.data(self, index, role)
+
+ sql_record = QSqlRecord()
+ sql_record = self.record(index.row())
+
+ return sql_record.value(role - Qt.UserRole)
+
+ def roleNames(self):
+ """Converts dict to hash because that's the result expected
+ by QSqlTableModel"""
+ names = {}
+ author = "author".encode()
+ recipient = "recipient".encode()
+ timestamp = "timestamp".encode()
+ message = "message".encode()
+
+ names[hash(Qt.UserRole)] = author
+ names[hash(Qt.UserRole + 1)] = recipient
+ names[hash(Qt.UserRole + 2)] = timestamp
+ names[hash(Qt.UserRole + 3)] = message
+
+ return names
+
+ # This is a workaround because PySide doesn't provide Q_INVOKABLE
+ # So we declare this as a Slot to be able to call it from QML
+ @Slot(str, str, str)
+ def send_message(self, recipient, message, author):
+ timestamp = datetime.datetime.now()
+
+ new_record = self.record()
+ new_record.setValue("author", author)
+ new_record.setValue("recipient", recipient)
+ new_record.setValue("timestamp", str(timestamp))
+ new_record.setValue("message", message)
+
+ logging.debug(f'Message: "{message}" \n Received by: "{recipient}"')
+
+ if not self.insertRecord(self.rowCount(), new_record):
+ logging.error("Failed to send message: {self.lastError().text()}")
+ return
+
+ self.submitAll()
+ self.select()