QT實戰經驗總結
- 在看書系統學習后,就開始實戰了,會遇到很多問題
- 1.信號和槽的思考
- 2.在python 或 C++ 代碼中,對 QML 代碼中控件的調用
- 關于在一個窗口上不斷打開新窗口
在看書系統學習后,就開始實戰了,會遇到很多問題
python案例
1.信號和槽的思考
-
當我練習簡單的信號和槽的時候,只是 print 一些文字,所以我的槽函數沒有封裝到類中。但是當我做一些復雜操作時,我發現就得用類來封裝起來。這里就涉及一個
engine.rootContext().setContextProperty("backend", backend)
作用是讓 backend 這個類,可以在 QML 中調用,因為類定義是在 python 中寫的 -
我在練習信號和槽的時候發現,我的python代碼(后端)可以給QML代碼(前端)發現號,而前端也可以給后端發現號。所以我發現這兩中發現號的方式是不一樣的。
-
前端給后端發,常用的比如點擊按鈕,
- 前端在你的 Button 中使用 onClicked{槽函數} 發射信號,對應的你的后端代碼得有 @Slot() 來接收這個信號
-
后端給前端發
- 后端中使用 Signal() 發射信號,對應的前端得用 Connections 接收信號,Connections是專門監聽后端信號的控件,它有監聽目標 target 屬性值和槽函數 function onFileSelected() 屬性值
-
2.在python 或 C++ 代碼中,對 QML 代碼中控件的調用
剛開始寫QT的時候,我就遇到這個問題
我在寫后端邏輯時,會涉及到對前端 QML 控件的調用。
比如,我點擊按鈕,改變按鈕或其他控件的屬性。
這里需要用到的就是 engin.rootobject()[0].findChild(Object,"name")
engin 是用 python 時通過 QQmlApplicationEngine() 創造的對象。
- rootObject()[0] 獲取到根控件,就是 Window 控件(我以為它是以樹形展開獲取,但是我測試發現只能獲取到根控件,就只有這一個)
- findChild(Object,“name”) 就是從根控件 Window 找名為 name 的子控件。
//通過點擊按鈕來改變該按鈕的文本
//只用函數實現不了,必須通過類才可以
//要注意的是代碼都是寫在 sys.exit(app.exec()) 前面的
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QObject, Slot
import sys
class Backend(QObject):def __init__(self, root_object, parent=None):super().__init__(parent)self.root_object = root_object@Slot()def say_hello(self):my_button = root_object.findChild(QObject, "myButton")if my_button:print("aaa",my_button.objectName())my_button.setProperty("text","bbb")
if __name__ == "__main__":app = QGuiApplication([])engine = QQmlApplicationEngine() engine.load("qml/main.qml")if not engine.rootObjects():sys.exit(-1)root_object = engine.rootObjects()[0]backend = Backend(root_object)engine.rootContext().setContextProperty("backend", backend)sys.exit(app.exec())
關于在一個窗口上不斷打開新窗口
class MainWindow(QObject):def __init__(self):super().__init__()self.engine = QQmlApplicationEngine()self.engine.rootContext().setContextProperty("mainwindow",self)self.engine.load("main_window.qml")if not self.engine.rootObjects():sys.exit(-1)self.main_window = self.engine.rootObjects()[0]self.first_window_component = QQmlComponent(self.engine)self.first_window_component.loadUrl("first_window.qml")if self.first_window_component.isReady():self.first_window = self.first_window_component.create()if self.first_window is None:print(self.first_window_component.errorString())else:print(self.first_window_component.errors())self.second_window_component = QQmlComponent(self.engine)self.second_window_component.loadUrl("second_window.qml")if self.second_window_component.isReady():self.second_window = self.second_window_component.create()if self.second_window is None:print(self.second_window_component.errorString())else:print(self.second_window_component.errors())@Slot()def close(self):self.main_window.close()@Slot()def first_window_close(self):self.first_window.close()@Slot()def second_window_close(self):self.second_window.close()if __name__ == "__main__":app = QGuiApplication(sys.argv)main_window = MainWindow()sys.exit(app.exec())