PyQt5中QQuickWidget内RadialBar仪表盘无法刷新的问题咨询
Hey there! I see you've been stuck on this for two days—let's get your RadialBar updating properly inside QQuickWidget. The core issue here is that you're using two separate QML engine instances right now, so the signals you're connecting aren't affecting the RadialBar inside your main window's QQuickWidget. Let's break down the fix step by step.
What's Wrong with Your Current Code?
You're loading qml_widget.qml twice:
- Once via
window.batteryCWidget.setSource()(this is the visible instance in your main window) - Again via
QQmlApplicationEngine.load()(this is a completely separate, invisible QML window)
When you connect batteryWidget.randomValue to root.setValue, you're updating the second invisible instance—not the one in your QQuickWidget. That's why you don't see any changes!
Step-by-Step Solution
1. Remove Redundant QQmlApplicationEngine Code
We only need to work with the QML engine embedded in your QQuickWidget. Delete all lines related to QQmlApplicationEngine, engine.rootContext(), engine.load(), and the root variable from that engine.
2. Use QQuickWidget's Own Context and Root Object
Instead, get the engine and context directly from batteryCWidget, then bind your MyClass instance to that context. Here's the revised main program code:
if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = GUI_MainWindow() # Register your RadialBar type (keep this line) qmlRegisterType(RadialBar, "SDK", 1, 0, "RadialBar") # Access the QQuickWidget's built-in engine and context qml_engine = window.batteryCWidget.engine() qml_context = qml_engine.rootContext() # Create your data update class and bind it to the QML context batteryWidget = MyClass() qml_context.setContextProperty("batteryWidget", batteryWidget) # Load the QML into the QQuickWidget window.batteryCWidget.setSource(QUrl('qml_widget.qml')) # Get the root object of the visible QML instance qml_root = window.batteryCWidget.rootObject() # Set up the timer to trigger data updates timer = QTimer() timer.start(200) timer.timeout.connect(batteryWidget.random_value) # Connect the signal to the correct QML root instance batteryWidget.randomValue.connect(qml_root.setValue) window.show() sys.exit(app.exec_())
3. Ensure RadialBar Triggers Redraw on Value Change
Looking at your RadialBar class, make sure the value property's setter emits the valueChanged signal and calls update() to force a repaint. Add these getter/setter methods to your RadialBar class:
@property def value(self): return self._Value @value.setter def value(self, new_value): if self._Value != new_value: self._Value = new_value self.valueChanged.emit() self.update() # Trigger a redraw with the new value
This ensures that when actVal changes in QML (via setValue()), the RadialBar's value property updates immediately and refreshes the visual display.
Why This Works
- We're now working exclusively with the QML engine tied to your
QQuickWidget, so all context properties and signal connections target the visible RadialBar in your main window. - The
update()call in the RadialBar's value setter guarantees the widget redraws itself whenever the data changes, making the new value visible on screen.
Give these changes a try—your RadialBar should start updating every 200ms as expected!
内容的提问来源于stack exchange,提问作者Karol Siegieda

