How can I get the radio button value from a .qml file using PyQt 5?
The .qml file is as follows:
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
visible: true
width: 600
height: 500
title: "HelloApp"
RadioButton {
id: button1
text: "1"
objectName: "radio_button"
}
TextInput {
id: text_input
objectName: "Textinput"
x:300
y:300
width: 80
height: 20
}
Button {
id: button_execute
x: 158
y: 341
width: 211
height: 36
text: qsTr("Execute")
onClicked: {
con.on_execute()
}
}
}
The Python code for reading this .qml file is as follows:
import sys
from os.path import abspath, dirname, join
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSlot
class Bridge(QObject):
@pyqtSlot()
def on_execute(self):
win = engine.rootObjects()[0]
# This will give me the value of text input
text_val = win.findChild(QObject, "Textinput").property("text")
# How to get the radio button value if it's checked or not checked?
app = QGuiApplication(sys.argv)
if __name__ == '__main__':
# Reading the qml file
engine = QQmlApplicationEngine()
context = engine.rootContext()
bridge = Bridge()
context.setContextProperty("con", bridge)
qmlFile = join(dirname(__file__), 'qml_test_1.qml')
engine.load(abspath(qmlFile))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
How can I know if the radio button is checked or not? I tried using objectName. But that does not work.
CodePudding user response:
Don't use object names. It is bad practice. Use signals and slots or models.
Example:
File main.py
import sys
from os.path import abspath, dirname, join
from PyQt5.QtGui import QGuiApplication
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtCore import QObject, pyqtSlot
class App(QObject):
def __init__(self, parent=None):
super().__init__(parent)
self.current_rb_text = ""
@pyqtSlot(str)
def set_current_rb_text(self, text: str):
self.current_rb_text = text
@pyqtSlot()
def on_execute(self):
print(self.current_rb_text)
app = QGuiApplication(sys.argv)
if __name__ == '__main__':
# Reading the qml file
engine = QQmlApplicationEngine()
context = engine.rootContext()
bridge = App()
context.setContextProperty("App", bridge)
qmlFile = join(dirname(__file__), 'main.qml')
engine.load(abspath(qmlFile))
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
File MyRadioButton.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
RadioButton {id:btn
onClicked:App.set_current_rb_text(btn.text)
}
File main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.14
ApplicationWindow {
visible: true
width: 600
height: 500
title: "HelloApp"
ColumnLayout{
MyRadioButton {
id: button1
text: "1"
objectName: "radio_button"
}
MyRadioButton {
id: button2
text: "2"
objectName: "radio_button"
}
MyRadioButton {
id: button3
text: "3"
objectName: "radio_button"
}
}
TextInput {
id: text_input
objectName: "Textinput"
x:300
y:300
width: 80
height: 20
}
Button {
id: button_execute
x: 158
y: 341
width: 211
height: 36
text: qsTr("Execute")
onClicked: {
App.on_execute()
}
}
}
Note:
You are using pyqt5 which is very old. I recommend you to use PySide6.3 since it is the official Qt binding and it has better support for QML. For instance, here you could have just declared a property in Python and bind it to the radio button text.