python qt信号在qml 的使用_Python和C++混合使用QML开发GUI

pyqt和qml结合的中文资很少,在baidu上搜索,基本上就是浪费时间。在国外的blog上,有零星的几篇,但是介绍好的少。在stackoverflow上看到一篇关于pyside,发现pyside,发现pyside果然给力,那就开始我们的pyside游戏之旅吧。

【编辑器】

目前的编辑环境是,Eclipse+PyDev, Erics, QtCreator这三个工具一起使用。用前两者进PY代码编辑,用QtCreator进行QML编辑和设计。

【概要】

用PyQt,C++,QML实现一个简单但的文本输入框值得取得和设置。从编码角度来看,我们需要在Python中调用QML的function方法,并通过参数传递把python中设定的变量值给QML.需要在QML中调用Python定义的函数方法,并把QML中InputText的Text值传递给Python.无论控件和业务逻辑多复杂都是如此。

Python代码

import sys

from PySide import QtCore, QtDeclarative, QtGui

class QtInterface(QtCore.QObject):

signaller_in_txt = QtCore.Signal(str)

signaller_out_txt = QtCore.Signal()

def __init__(self):

QtCore.QObject.__init__(self)

self.in_txt = "test"

#@的这种声明方式,会在后面的部分介绍,并且参考链接中,有一篇文也介绍的很清晰。

#这是一个不带参数的Slot函数。

@QtCore.Slot()

def getInputText(self):

print self.in_txt

#这个一个带参数的Slot函数,我们就是利用这个参数,在QML中,调用这个函数,并把InputText的text值发送过来,并且在函数中,打印出这个传递值。

@QtCore.Slot(str)

def setInputText(self, text):

print text

#在updateValues函数中,通过信号发射,调用QML中的function函数,并将对控件的设置值,传递过去。信号变量声明,在类中,和与对应的QML函数简历毁掉联系,是在main函数中完成的。

def updateValues(self):

# self.signaller_in_txt.emit(str(self.in_txt))

self.signaller_out_txt.emit()

#MainView是主要View视图,继承了基类,QDeclarativeView,继承了最大化,最小话和关闭窗体的机能。

class MainView(QtDeclarative.QDeclarativeView):

def __init__(self, parent=None):

#构造父类

super( MainView, self).__init__(parent)

#设定窗体Title内容

self.setWindowTitle("Counter")

#设定与本地QML关联

self.setSource( QtCore.QUrl.fromLocalFile('abc.qml'))

#设定窗体尺寸变化的模式,继承了父类的模式

self.setResizeMode( QtDeclarative.QDeclarativeView.SizeRootObjectToView)

#创建一个QtGui的应用实例

qApplication = QtGui.QApplication(sys.argv)

#主视图创建

window = MainView()

#显示主视图

window.show()

#取得用于解析QML的类实例

qcontext = window.rootContext()

interface = QtInterface()

#将用户自己的QtObject子类和窗体类建立连接

qcontext.setContextProperty("qInterface", interface)

#将信号和QML函数建立映射关联。

interface.signaller_score_a.connect(window.rootObject().updateScoreA)

interface.signaller_in_txt.connect(window.rootObject().updateInText)

interface.signaller_out_txt.connect(window.rootObject().getInTxt)

#退出应用

sys.exit(qApplication.exec_())

QML代码

QML语言基本UI元素的描述信息和功能函数,QML本身可以通过自己的函数定义执行来完成一定程度上功能,完全和背后的语言(C++,Python)脱离关系。而且在很多的平台上使用,甚至包括移动平台,可以和我的WEB服务器很好的链接,传递数据。

import QtQuick 1.1

Rectangle {

id: rectangle1

width: 480

height: 272

gradient: Gradient {

GradientStop {

id: gradientStop1

position: 0

color: "#ffffff"

}

GradientStop {

position: 1

color: "#abc09f"

}

}

//UML中的函数,要通过emit发射信号调用。

function updateInText(string) {

in_txt.text = string

}

function updateIn() {

in_txt.text = "ozzy"

}

//在Python中,通过emit调用getInTxt函数

function getInTxt() {

//console.log基本就是JavaScript的用法。

console.log("debug")

return (in_txt.text)

}

Text {

id: score_a

x: 150

y: 74

width: 131

height: 48

text: qsTr("Text")

verticalAlignment: Text.AlignVCenter

font.pixelSize: 12

}

MouseArea {

id: a_scored

x: 303

y: 200

}

Rectangle {

id: team_a

x: 150

y: 148

width: 127

height: 46

color: "#4e3a3a"

radius: 10

TextInput {

id: team_a_txt

x: 24

y: 13

width: 80

height: 20

text: qsTr("A")

selectionColor: "#316cc4"

horizontalAlignment: TextInput.AlignHCenter

font.pixelSize: 12

}

MouseArea {

id: team_a_score_ma

x: 1

y: 0

width: 126

height: 46

onClicked: {

qInterface.aScored()

}

}

}

TextInput {

id: in_txt

x: 345

y: 67

width: 80

height: 20

text: qsTr("InputText")

selectionColor: "#316cc4"

font.pixelSize: 12

MouseArea {

id: in_txt_ma

x: -17

y: 77

width: 115

height: 57

z: 2

//直接在MouseArea中添加对应的事件处理

onClicked: {

//qInterface是在Python中建立的映射关系,通过这个对象实例,就可以直接调用Python中的函数方法,并且可以传递参数

qInterface.setInputText(in_txt.text)

//下面的这个函数被注释掉了,因为getText()是一个C++写的方法

//console.log(qInterface.getText())

}

}

}

Rectangle {

id: get_in_text

x: 322

y: 148

width: 127

height: 46

color: "#4e3a3a"

radius: 10

Text {

id: text1

x: 38

y: 15

width: 40

height: 16

text: qsTr("Enter")

font.pixelSize: 12

}

}

}

C++代码

#ifndef LOGIN_H

#define LOGIN_H

#include

class Login: public QObject

{

Q_OBJECT

public:

//Q_INVOKABLE关键字,可以让QML直接调用C++方法。相当于 濮阳天python中的@QtCore.Slot()

Q_INVOKABLE QString getText(void) const;

Login(QObject *parent = 0);

virtual ~Login();

signals:

void setInputText(const QString &s);

public slots:

void setText(const QString &s);

};

#endif // LOGIN_H

#include "login.h"

Login::Login(QObject *parent)

:QObject(parent)

{

QObject::connect(this, SIGNAL(setInputText(QString)), this, SLOT(setText(QString)));

}

Login::~Login() {

}

QString LS::getText(void) const

{

return "from C++ Code";

}

void LS::setText(const QString &s) {

qDebug("this is string.");

qDebug("%s", s.toLocal8Bit().data());

}

【后记】

上面的代码可以看到,PyQt和C++公用一个QML代码,QML几乎不变(不是几乎,就是一样的)。

PyQT(PySide)更适应快速开发,写Python也更好玩。用C++实现性能要求比较高的共同部分,则更有优势。

Python中QML调用Python函数,只要把python的函数声明为@QtCore.Slot

Python调用QML函数,需要定义信号和connect QML的函数。

C++是,UML调用C++函数,只要把C++函数声明过为Q_INVOKABLE

C++调用QML函数,需要声明Signal和Connect Slot函数。

这点Python和C++的流程保持一致。

【参考】

http://qt-project.org/wiki/PySide

在QML中使用JavaScript和Sqlite

http://thierry-xing.iteye.com/blog/1387855

关于QML中调用qt类中的信号,槽,成员函数,属性做记录

http://huangchunquanmaker.blog.163.com/blog/static/107408483201104101331193/

Connecting Qt signal to QML function

http://blog.chinaunix.net/uid-12664992-id-129937.html

@符号在python中的作用

http://ar.newsmth.net/thread-8f2dbaba27a86d-1.html

Filling and reading QML UI forms from python.

http://qt-project.org/wiki/Filling-and-reading-QML-UI-forms-from-Python

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt中调用Python脚本程序可以使用QProcess类,而在qml控件和Python脚本程序之间的通信可以使用Python的标准输入输出流。以下是一个简单的示例: main.cpp: ```c++ #include <QCoreApplication> #include <QProcess> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QProcess *process = new QProcess(&a); process->setProgram("python"); process->setArguments(QStringList() << "script.py"); QObject::connect(process, &QProcess::readyReadStandardOutput, [&]() { QString output = process->readAllStandardOutput(); qDebug() << "Python output: " << output; }); process->start(); return a.exec(); } ``` script.py: ```python print("Python script is running...") while True: input_str = input() if input_str == "quit": break print("Received input: " + input_str) ``` Qml中可以使用Qt的QProcess类或PyQt的QProcess类来调用Python脚本程序,也可以使用PyQt的QPythonRunner类直接运行Python代码。在qml中与Python脚本程序之间的通信可以使用Python的标准输入输出流。 例如,使用Qt的QProcess类: ```qml import QtQuick 2.0 Item { id: root Button { text: "Run Python script" onClicked: { var process = Qt.createQmlObject('import QtQuick 2.0; import QtQuick.Controls 2.0; Process { program: "python"; arguments: ["script.py"]; }', root); process.readyReadStandardOutput.connect(function() { var output = process.readAllStandardOutput(); console.log("Python output: " + output); }); process.start(); } } } ``` 使用PyQt的QProcess类: ```qml import QtQuick 2.0 import PyQt5.QtCore 1.0 import PyQt5.QtGui 1.0 import PyQt5.QtWidgets 1.0 Item { id: root Button { text: "Run Python script" onClicked: { var process = new QProcess(); process.setProgram("python"); process.setArguments(["script.py"]); process.readyReadStandardOutput.connect(function() { var output = process.readAllStandardOutput(); console.log("Python output: " + output); }); process.start(); } } } ``` 使用PyQt的QPythonRunner类: ```qml import QtQuick 2.0 import PyQt5.QtCore 1.0 import PyQt5.QtGui 1.0 import PyQt5.QtWidgets 1.0 Item { id: root Button { text: "Run Python code" onClicked: { var runner = new QPythonRunner(); runner.runCode("print('Hello from Python!')"); runner.readyReadStandardOutput.connect(function() { var output = runner.readAllStandardOutput(); console.log("Python output: " + output); }); } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值