我试图弄清楚如何将文本字段输入的数据传递给Python类。我认为解决这个问题的方法是使用信号和插槽;但是,我正在widget.QML(主QML类)中使用传递数据的自定义QML组件。我需要这样做,以便对通过TextField传入的数据执行更复杂的操作
我对如何将数据从BasicContainer.qml传递到python类感到困惑,并且不确定widget.qml类中的逻辑是否支持,因为它使用嵌套模型。我已经附上了一个例子,希望能够抓住控制流的要点。我可以在我添加的widget.qml中使用一个基本信号,但是如果我在BasicContainer.qml中执行相同的操作,我会得到一个PySide6.QtQuick.QQuickItem object has no attribute 'displayValueChanged'
main.py
import os
import sys
from pathlib import Path
sys.path.append(os.path.join(os.path.dirname(sys.path[0]), ".."))
from PySide6.QtCore import Property, QUrl, QObject, Qt, QCoreApplication, Slot
from PySide6.QtGui import QGuiApplication, QStandardItem, QStandardItemModel
from PySide6.QtQuick import QQuickView
CURRENT_DIRECTORY = Path(__file__).resolve().parent
# QstandardItem roles
SetText = Qt.UserRole + 1
class ControlledSignalWidget(QObject):
def __init__(self):
super().__init__()
self._model = QStandardItemModel()
# self._model.setItemRoleNames({Qt.DisplayRole: b"display"})
self._setpoints_models = []
@Property(QObject, constant=True)
def model(self):
return self._model
@Slot(int, result=QObject)
def setpoints(self, idx):
return self._setpoints_models[idx]
# create custom number of widgets
def create_widgets(self, widgets, allComponents):
counter = 1
# Iterates for the amount of widgets created
for general, widget in widgets.items():
# for key in widget:
print("Adding new widget")
item = QStandardItem(widget["Header"])
self._model.appendRow(item)
self.create_setpoints(allComponents["item" + str(counter) + "Components"])
print("Added widget")
counter += 1
def create_setpoints(self, component):
setpoints_model = QStandardItemModel()
setpoints_model.setItemRoleNames({SetText: b"textField"})
for subWidget in component:
print(subWidget)
item = QStandardItem()
item.setData(subWidget["title"], SetText)
setpoints_model.appendRow(item)
self._setpoints_models.append(setpoints_model)
def display(s):
print(s)
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
view = QQuickView()
view.setResizeMode(QQuickView.SizeViewToRootObject)
url = QUrl.fromLocalFile(os.fspath(CURRENT_DIRECTORY / "widget.qml"))
def handle_status_changed(status):
if status == QQuickView.Error:
QCoreApplication.exit(-1)
widgets = {
"widget1": {"Header": "Header Text"},
"widget2": {"Header": "Header 2 Text"},
}
item1Components = [{"title": "widget1random"}, {"title": "widget1random2"}]
item2Components = [{"title": "widget2random"}, {"title": "widget2random2"}]
allComponents = {
"item1Components": item1Components,
"item2Components": item2Components,
}
mainWidget = ControlledSignalWidget()
mainWidget.create_widgets(widgets, allComponents)
view.rootContext().setContextProperty("mainWidget", mainWidget)
view.statusChanged.connect(
handle_status_changed, Qt.ConnectionType.QueuedConnection
)
view.setSource(url)
# SIGNAL CONNECTION MADE
root = view.rootObject()
root.displayValueChanged.connect(display)
view.show()
sys.exit(app.exec())
widget.qml
import QtQuick 2.0
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.12
Item {
id: root
width: 1000
height: 800
signal displayValueChanged(string setpoint)
GridLayout{
columns: 3
Repeater{
id: repeater1
model: mainWidget.model
ColumnLayout{
property int outerIndex: index
Repeater{
id: repeater2
model: mainWidget.setpoints(outerIndex)
ColumnLayout{
BasicContainer{
Component.onCompleted: {
//Signal called
displayValueChanged(inputText)
}
}
}
}
}
}
}
}
BasicContainer.qml
import QtQuick 2.12
import QtQuick.Controls.Material 2.15
import QtQuick.Layouts 1.12
Item {
id: basicContainerItem
width: 300
height: 60
visible: true
signal valueChanged()
property alias inputText: containerInput.text
Rectangle {
id: rectangle
width: parent.width
ColumnLayout {
TextField {
id: containerInput
visible: true
placeholderText: qsTr("Text Field")
text: "Default value"
// Contended line
//textColor: "#FF3333"
onAccepted: {
console.log(text)
basicContainerItem.valueChanged()
}
}
}
}
}
重要编辑:
我修改了代码,使用信号将值从BasicContainer类一直传递到Python,因此当您进行文本输入并按enter键时,将记录您输入的新文本。这应该解决一切问题;但是,当我尝试进行任何样式更改(如BasicContainer.qml:textColor: "#FF3333"
中的文本颜色更改行)时,将导致我的应用程序中断,从而导致此错误:
root.displayValueChanged.connect(display) AttributeError 'Nonetype' object has no attribute 'displayValueChanged'
没关系,看来正确的解决方案正是我上面提到的;除了我使用textColor的那部分,因为很明显,这应该是
color
,而不是textColor
。然而,信号工作正常,这是我解决这个问题的目标相关问题 更多 >
编程相关推荐