Здравствуйте, я следую по этой ссылке QML, SQL и интеграция PySide
Я получаю эту ошибку при нажатии кнопки «Отправить»:
TypeError: Property 'send_message' of object SqlConversationModel(0x564692696f40) is not a function
это мой main.py:
import logging
from PySide2.QtCore import QDir, QFile, QUrl
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtSql import QSqlDatabase
from t2_SqlQmlPython.python.sqlDialog import SqlConversationModel
UI = "../ui/chat.qml"
logging.basicConfig(filename="chat.log", level=logging.DEBUG)
logger = logging.getLogger("logger")
def connectToDatabase():
database = QSqlDatabase.database()
if not database.isValid():
database = QSqlDatabase.addDatabase("QSQLITE")
if not database.isValid():
logger.error("Cannot add database")
write_dir = QDir()
if not write_dir.mkpath("."):
logger.error("Failed to create writable directory")
# Ensure that we have a writable location on all devices.
filename = "{}/chat-database.sqlite3".format(write_dir.absolutePath())
# When using the SQLite driver, open() will create the SQLite
# database if it doesn't exist.
database.setDatabaseName(filename)
if not database.open():
logger.error("Cannot open database")
QFile.remove(filename)
if __name__ == "__main__":
app = QGuiApplication()
connectToDatabase()
sql_conversation_model = SqlConversationModel()
engine = QQmlApplicationEngine()
# Export pertinent objects to QML
engine.rootContext().setContextProperty("chat_model", sql_conversation_model)
engine.load(QUrl(UI))
app.exec_()
, и это мой sqlDialog.py:
import datetime
import logging
from PySide2.QtCore import Qt, Slot
from PySide2.QtSql import QSqlDatabase, QSqlQuery, QSqlRecord, QSqlTableModel
table_name = "Conversations"
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)
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 get_print_tb(self):
logging.debug("mohsen is checking")
def setRecipient(self, recipient):
if recipient == self.recipient:
pass
self.recipient = recipient
filter_str = (
"(recipient = '{}' AND author = 'Me') OR " "(recipient = 'Me' AND author='{}')"
).format(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
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('Message: "{}" \n Received by: "{}"'.format(message, recipient))
if not self.insertRecord(self.rowCount(), new_record):
logging.error("Failed to send message: {}".format(self.lastError().text()))
return
self.submitAll()
self.select()
и chat.qml:
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: window
title: qsTr("Chat")
width: 640
height: 960
visible: true
ColumnLayout {
anchors.fill: parent
ListView {
id: listView
Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: pane.leftPadding + messageField.leftPadding
displayMarginBeginning: 40
displayMarginEnd: 40
verticalLayoutDirection: ListView.BottomToTop
spacing: 12
model: chat_model
delegate: Column {
readonly property bool sentByMe: model.recipient !== "Me"
anchors.right: sentByMe ? parent.right : undefined
spacing: 6
Row {
id: messageRow
spacing: 6
anchors.right: sentByMe ? parent.right : undefined
Rectangle {
width: Math.min(messageText.implicitWidth + 24, listView.width - messageRow.spacing)
height: messageText.implicitHeight + 24
radius: 15
color: sentByMe ? "lightgrey" : "#ff627c"
Label {
id: messageText
text: model.message
color: sentByMe ? "black" : "white"
anchors.fill: parent
anchors.margins: 12
wrapMode: Label.Wrap
}
}
}
Label {
id: timestampText
text: Qt.formatDateTime(model.timestamp, "d MMM hh:mm")
color: "lightgrey"
anchors.right: sentByMe ? parent.right : undefined
}
}
ScrollBar.vertical: ScrollBar {}
}
Pane {
id: pane
Layout.fillWidth: true
RowLayout {
width: parent.width
TextArea {
id: messageField
Layout.fillWidth: true
placeholderText: qsTr("Compose message")
wrapMode: TextArea.Wrap
}
Button {
id: sendButton
text: qsTr("Send")
enabled: messageField.length > 0
onClicked: {
chat_model.send_message("machine", messageField.text, "me");
messageField.text = "";
}
}
}
}
}
}
и это put is:
TypeError: Property 'send_message' of object SqlConversationModel(0x564692696f40) is not a function
Я перешел по этой ссылке class-visible-to-qml-error-in-fashion-typeerror-property-of-object-is , но я не мог это понять out.
Что я делаю не так?