PyQt Note
PyQt notes
1. PyQt5 QML 界面
.py
from PyQt5.QtGui import QGuiApplication
from PyQt5 import QtQml
if __name__ == '__main__':
path = 'QtQuick/test/qml/main.qml'
app = QGuiApplication([])
engine = QtQml.QQmlApplicationEngine()
engine.load(path)
app.exec_()
main.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: test
visible: true
width: 400; height: 700
color: "#ffffff"
Text {
text: "hello world!";
}
Button{
id: btn
property alias cellColor1: btnColorRect.color//cunstom var/property
text: "你好hello";
font.family: "Alibaba puhuiti";
font.pointSize: 13;
// background.color: "#aacccc"
background: Rectangle {
id: btnColorRect
anchors.fill: parent
color: "#8000ff"
}
anchors.centerIn: parent
MouseArea{
anchors.fill: parent
hoverEnabled: true
onEntered:{
btnColorRect.color = "#0000ff"
}
onExited: {
btnColorRect.color = "#8000ff"
}
}
}
Grid {
id: colorGrid
// x: 4;
anchors{
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 4
}
rows: 2; columns: 3; spacing: 3
MyColorPicLabel { cellColor: "red"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "green"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "blue"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "yellow"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "steelblue"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "#ff0080"; onClicked: btnColorRect.color = cellColor }
}
}
MyColorPicLabel.qml
import QtQuick 2.4
Item {
id: container
property alias cellColor: rectangle.color//cunstom var/property
signal clicked(color cellColor)//singal
width: 70; height: 40
Rectangle {
id: rectangle
border.color: "#380071"
border.width: 2
anchors.fill: parent
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: container.clicked(container.cellColor)//触发信号
onEntered:{
// console.log("hello");
rectangle.border.width = 4
}
onExited:{
// console.log("no hello");
rectangle.border.width = 2
}
}
}
2. QML 与 Python Class 互通
python class 定义要点
- 需要继承 QObject 类
__init__()
函数需要调用父类的 构造函数- QML 里调用的函数必须是槽函数,用 @pyqtSlot(…) 修饰
class MyScreen(QObject):
screens = QGuiApplication.screens()
screenCount = 0
def __init__(self) -> None:
super().__init__() # 调用父类的__init__() 这样才能加载该类至 QML 里
self.screens = QGuiApplication.screens()
for i in self.screens:
self.screenCount += 1
@pyqtSlot(int, result=QRect)
def getScreenSize(self, id):
"""[getScreenSize]
Args:
id ([int]): [id of screen]
Returns:
[QRect]: [screen's size]
"""
if(id >= self.screenCount or id < 0):
return QRect(0,0,0,0)
return self.screens[id].geometry()
@pyqtSlot(result=str) # 使用pyqtSlot() 修饰该函数,这样 QML 里才能知道函数的参数与返回值
def test(self):
return "我是python槽函数传递的字符串"
@pyqtSlot(str)
def printlog(self, str):
print(str)
将python class 加载进 QML
# create screen obejct
scr = MyScreen()
# 注册 Python 类至 QML 根节点
engine.rootContext().setContextProperty("scr", scr)
这样QML 里可以使用 scr 对象了。
QML 信号定义和触发
定义信号
ApplicationWindow {
id: mainWin
// signal
signal myLogSignal(string log)
....
}
触发信号
Button{
text: "点我输出log";
font.family: "Alibaba puhuiti";
font.pointSize: 13;
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: btn1.top
anchors.bottomMargin: 10
MouseArea{
anchors.fill: parent
onClicked:{
mainWin.myLogSignal("我是QML 里信号发来的字符串")
}
}
}
QML 信号绑定 Python 槽函数
# QML 信号连接 Python 槽函数
my_obj = engine.rootObjects()[0] # 获取根节点
my_obj.myLogSignal.connect(scr.printlog) # 绑定信号和槽
Python 调用QML 函数
定义函数
ApplicationWindow {
...
function qmlLog(str){
console.log(str);
}
....
}
python 调用
# QML 信号连接 Python 槽函数
my_obj = engine.rootObjects()[0] # 获取根节点
# 调用QML 函数
my_obj.qmlLog("我是qml 函数输出的字符串")
源码
main.py
from PyQt5.QtCore import QObject, QRect, pyqtSlot
from PyQt5 import QtQml
from PyQt5.QtGui import QGuiApplication
class MyScreen(QObject):
screens = QGuiApplication.screens()
screenCount = 0
def __init__(self) -> None:
super().__init__() # 调用父类的__init__() 这样才能加载该类至 QML 里
self.screens = QGuiApplication.screens()
for i in self.screens:
self.screenCount += 1
@pyqtSlot(int, result=QRect)
def getScreenSize(self, id):
"""[getScreenSize]
Args:
id ([int]): [id of screen]
Returns:
[QRect]: [screen's size]
"""
if(id >= self.screenCount or id < 0):
return QRect(0,0,0,0)
return self.screens[id].geometry()
@pyqtSlot(result=str) # 使用pyqtSlot() 修饰该函数,这样 QML 里才能知道函数的参数与返回值
def test(self):
return "我是python槽函数传递的字符串"
@pyqtSlot(str)
def printlog(self, str):
print(str)
if __name__ == '__main__':
path = 'QtQuick/grabImage/qml/main.qml'
app = QGuiApplication([])
engine = QtQml.QQmlApplicationEngine()
# create screen obejct
scr = MyScreen()
# 注册 Python 类至 QML 根节点
engine.rootContext().setContextProperty("scr", scr)
engine.load(path)
# QML 信号连接 Python 槽函数
my_obj = engine.rootObjects()[0] # 获取根节点
my_obj.myLogSignal.connect(scr.printlog) # 绑定信号和槽
# 调用QML 函数
my_obj.qmlLog("我是qml 函数输出的字符串")
app.exec_()
main.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
id: mainWin
visible: true
width: 400; height: 700
color: "#ffffff"
// signal
signal myLogSignal(string log)
Text {
text: "hello world!";
}
Button{
id: btn
property alias cellColor1: btnColorRect.color//cunstom var/property
text: "你好hello";
font.family: "Alibaba puhuiti";
font.pointSize: 13;
// background.color: "#aacccc"
background: Rectangle {
id: btnColorRect
anchors.fill: parent
color: "#8000ff"
}
anchors.centerIn: parent
MouseArea{
anchors.fill: parent
hoverEnabled: true
onEntered:{
btnColorRect.color = "#0000ff"
}
onExited: {
btnColorRect.color = "#8000ff"
}
onPressed: {
btnColorRect.color = "#800008"
}
onClicked:{
// grabWin.setFlags(Qt::FramelessWindowHint)
console.log("hello world");
}
}
}
Button{
id: btn1
font.family: "Alibaba puhuiti";
font.pointSize: 13;
text: "点我输出屏幕2分辨率";
property rect sereen_size: scr.getScreenSize(1) // get size of screen 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: btn.top
anchors.bottomMargin: 10
MouseArea{
anchors.fill: parent
onClicked:{
console.log("x =", parent.sereen_size.x)
console.log("y =", parent.sereen_size.y)
console.log("width =", parent.sereen_size.width)
console.log("height =", parent.sereen_size.height)
}
}
}
Button{
text: "点我输出log";
font.family: "Alibaba puhuiti";
font.pointSize: 13;
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: btn1.top
anchors.bottomMargin: 10
MouseArea{
anchors.fill: parent
onClicked:{
mainWin.myLogSignal("我是QML 里信号发来的字符串")
}
}
}
Grid {
id: colorGrid
// x: 4;
anchors{
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
bottomMargin: 4
}
rows: 2; columns: 3; spacing: 3
MyColorPicLabel { cellColor: "red"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "green"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "blue"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "yellow"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "steelblue"; onClicked: btnColorRect.color = cellColor }
MyColorPicLabel { cellColor: "#ff0080"; onClicked: btnColorRect.color = cellColor }
}
function qmlLog(str){
console.log(str);
}
}
MycolorPicLabel.qml
import QtQuick 2.4
Item {
id: container
property alias cellColor: rectangle.color//cunstom var/property
signal clicked(color cellColor)//singal
width: 70; height: 40
Rectangle {
id: rectangle
border.color: "#380071"
border.width: 2
anchors.fill: parent
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: container.clicked(container.cellColor)//触发信号
onEntered:{
// console.log("hello");
rectangle.border.width = 4
}
onExited:{
// console.log("no hello");
rectangle.border.width = 2
}
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!