Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数
话接上篇。通过前几篇博客,我们实现在Lua脚本中执行Qt类中函数的方法,以及在Lua脚本中连接Qt对象的信号与槽。
但是,我们也能发现,如果希望在Lua脚本中执行Qt类的函数,就必须绑定一个真正实现功能的函数。如QWidget::show(),需要写一个在栈中取出widget指针,widget调用show()函数的方式。如果希望在Lua中调用大量函数,就需要编写大量的C++实现函数。有没有什么省时省力的好方法呢?
上一篇中我们实现了在Lua脚本中连接信号与槽。我们只是传过去了两个QObject的对象,和两个字符串的函数名。我们并没有具体实现那个函数,但是槽函数顺利执行了。这给了笔者启发。如果我传过去一个函数名,理论上我可以找一个信号连接并激发它,也就达到了执行的目的。
OK,我们写这样一个函数:
static int exec(lua_State *state)
{
QObject* obj = (QObject* )tolua_tousertype(state, , );
const char * slot = tolua_tostring(state, , ); if(obj != NULL)
{
RunSLOT run;
QObject::connect(&run, SIGNAL(sendSignal()),
obj, QString("1%0()").arg(slot).toLocal8Bit().data());
} return ;
}
取得QObject对象,以及字符串的槽函数名称。然后我们新建了一个RunSLOT对象,连接了run和obj对象。这样就能执行字符串代表的函数?
继续看RunSLOT类:
#ifndef RUNSLOT_H
#define RUNSLOT_H #include <QObject> class RunSLOT : public QObject
{
Q_OBJECT
public:
RunSLOT(QObject *parent = );
~RunSLOT(); signals:
void sendSignal();
}; #endif // RUNSLOT_H
#include "runslot.h" RunSLOT::RunSLOT(QObject *parent) :
QObject(parent)
{
} RunSLOT::~RunSLOT()
{
emit sendSignal();
}
在析构是发出sendSignal信号,激发槽函数。而RunSLOT类对象run在遇到‘}’自动析构(C++局部变量原则),也就间接的执行了槽函数。
在绑定函数时将exec绑定到类里,然后写个测试脚本看看:
widget = QWidget:new()
widget:exec("show") button = QPushButton:new()
button:exec("show") connect(button, "clicked()", widget, "hide()")
成功显示一个窗体,一个按钮。
完整main.cpp如下:
// own
#include "include/lua.hpp"
#include "qlua.h"
#include "runslot.h" // qt
#include <QWidget>
#include <QApplication>
#include <QFile>
#include <QDebug> static int connect(lua_State* state)
{
QObject * a = (QObject*)tolua_tousertype(state, , );
const char * signal = tolua_tostring(state, , );
QObject * b = (QObject*)tolua_tousertype(state, , );
const char * slot = tolua_tostring(state, , ); QObject::connect(a, QString("2%0").arg(signal).toLocal8Bit().data(),
b, QString("1%0").arg(slot).toLocal8Bit().data()); return ;
} static int exec(lua_State *state)
{
QObject* obj = (QObject* )tolua_tousertype(state, , );
const char * slot = tolua_tostring(state, , ); if(obj != NULL)
{
RunSLOT run;
QObject::connect(&run, SIGNAL(sendSignal()),
obj, QString("1%0()").arg(slot).toLocal8Bit().data());
} return ;
} static int QObject_delete(lua_State* state)
{
qDebug() << "delete Start";
QObject* obj = (QObject* )tolua_tousertype(state, , );
if(NULL != obj)
{
qDebug() << "delete~";
delete obj;
}
return ;
} static int QWidget_new(lua_State* state)
{
QWidget* widget = new QWidget();
tolua_pushusertype(state, widget, "QWidget");
return ;
} static int QPushButton_new(lua_State* state)
{
QPushButton* button = new QPushButton();
tolua_pushusertype(state, button, "QPushButton");
return ;
} static int QWidget_resize(lua_State* state)
{
QWidget* widget = (QWidget* )tolua_tousertype(state, , );
double a = tolua_tonumber(state, , );
double b = tolua_tonumber(state, , ); if(widget)
{
widget->resize((int)a, (int)b);
}
return ;
} int main(int argc, char * argv[])
{
Q_INIT_RESOURCE(resources);
QApplication a(argc, argv); QLua lua; lua.beginModule(""); lua.addType("QWidget", QObject_delete);
lua.moduleTypeFunction("new", QWidget_new);
lua.moduleTypeFunction("resize", QWidget_resize);
lua.moduleTypeFunction("exec", exec);
lua.endModule(); lua.addType("QPushButton", QObject_delete);
lua.moduleTypeFunction("new", QPushButton_new);
lua.moduleTypeFunction("exec", exec);
lua.endModule(); lua.endModule(); lua.pushFunction("connect", connect); // 读取资源文件
QFile file("../../LuaTest/test.lua");
file.open(QIODevice::ReadOnly | QIODevice::Text); QTextStream in(&file);
in.setCodec("UTF-8"); // 执行
lua.run(in.readAll()); return a.exec();
}
我们可以在将绑定exec函数写在QLua类里,添加类时就绑定这个函数。
当然,这个方法的局限性在于执行的函数无参数,而且必须是槽函数。如果想自由一个,可以在调用时写上参数,参数类型,C++这边判断并选择不同的信号连接方式,一劳永逸。
通过这个例子,我们可以发现,Qt本身就具备由字符串执行函数的能力,按照我的见解,这就是一种半动态。笔者会继续做下去,因为这个真的很有趣。
完整例程代码下载:http://pan.baidu.com/s/1sjFDiRb
转载注明出处:http://www.cnblogs.com/IT-BOY/
Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数的更多相关文章
- C++与Lua交互(四)
引言 通过前几篇,我们已经对Lua的C API有了一定的了解,如lua_push*.lua_is*.lua_to*等等.用C++调用Lua数据时,我们主要运用lua_getglobal与lua_pus ...
- C++与lua交互之C++访问lua
假设lua中: name="gzw" id=17010805 sex=man tab={ num=100, str="hello" } foo_one=func ...
- ListView使用自定义适配器的情况下实现适配器的文本和图标控件点击事件执行Activity界面中的方法
ListView使用的是自定义适配器,列表项的布局文件中含有文本和图标,实现文本区域和图标区域的点击事件. 实现思路:在自定义适配器MyArrayAdapter 类型中自定义接口和接口方法,分别设置文 ...
- Qt 使用qDebug() 打印Qlist 容器数据(将QDebug()定义成某个类的友元函数)
当QList<T>容器中的数据用qDebug() 打印时 ,假如 T 是内置类型(int float ...)与 打印一个字符串使用完全一样,假如T 是一个CustomerClass 那 ...
- 【转】shell编程下 特殊变量、test / [ ]判断、循环、脚本排错
[转]shell编程下 特殊变量.test / [ ]判断.循环.脚本排错 第1章 shell中的特殊变量 1.1 $# $# 表示参数的个数 1.1.1 [示例]脚本内容 [root@znix ~] ...
- Win32下 Qt与Lua交互使用(二):在Lua脚本中使用Qt类
话接上篇.成功配置好Qt+Lua+toLua后,我们可以实现在Lua脚本中使用各个Qt的类.直接看代码吧. #include "include/lua.hpp" #include ...
- Win32下 Qt与Lua交互使用(一):配置Qt下Lua运行环境
偶然间看到Lua这种脚本语言,有点兴趣,简单学习了一下. 发现Lua与C++之间可以实现非常强的交互性.Lua中可以使用C++中的函数,C++中也可以使用Lua中的函数.由此可以引发出很多奇思妙想了. ...
- Win32下 Qt与Lua交互使用:配置Qt下Lua运行环境
Lua与C++之间可以实现非常强的交互性.Lua中可以使用C++中的函数,C++中也可以使用Lua中的函数.由此可以引发出很多奇思妙想了. 简单来说,Lua动态的特性补充了C++的功能.当然,也看你具 ...
- Qt webKit可以做什么(四)--实现本地QObject和JavaScript交互
Qt webKit可以做什么(四)--实现本地QObject和JavaScript交互 Qt webKit可以做什么(四)--实现本地QObject和JavaScript交互
随机推荐
- 05_XML的解析_01_dom4j 解析
[简述] Xml文件出了给开发者看,更多情况使用程序读取xml文件里的内容,这叫做xml解析. 根据解析方式分为:DOM解析 和 SAX解析 [解析工具] (一). 使用DOM解析原理的工具: 1.J ...
- 学习C++ Primer 的个人理解(二)
本身就一定基础的读者我想变量常量这些概念应该已经不是问题了.但是本章还是有几个重点,需要特别留意一下的: 1.初始化和赋值是不同的操作 2.任何非0值都是true 3.使用新标准列表初始化,在有丢失精 ...
- Hdu 1042 N! (高精度数)
Problem Description Givenan integer N(0 ≤ N ≤ 10000), your task is to calculate N! Input OneN in one ...
- 九度OJ 1531 货币面值(网易游戏2013年校园招聘笔试题) -- 动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1531 题目描述: 小虎是游戏中的一个国王,在他管理的国家中发行了很多不同面额的纸币,用这些纸币进行任意的组合可以在 ...
- java nio使用方法(转)
最近由于工作关系要做一些Java方面的开发,其中最重要的一块就是Java NIO(New I/O),尽管很早以前了解过一些,但并没有认真去看过它的实现原理,也没有机会在工作中使用,这次也好重新研究一下 ...
- Pigcms中WeixinAction的简略版流程
if $this->ali = 0; 1.new wechat() //该类存于PigCms/lib/ORG/Wechat.class.php 2.list($content,$type) = ...
- 在JQuery和Js中,如何让ajax执行完后再继续往下执行 async
async (默认: true) 默认设置下,所有请求均为异步请求.如果需要发送同步请求,请将此选项设置为 false.注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行. var t ...
- 基于Hadoop生态圈的数据仓库实践 —— ETL
使用Hive转换.装载数据 1. Hive简介 (1)Hive是什么 Hive是一个数据仓库软件,使用SQL读.写.管理分布式存储上的大数据集.它建立在Hadoop之上,具有以下功能和 ...
- oracle,wamp,FZ突然出现问题,求解决方案(未解决,最终系统还原)
-----背景------- 系统:win7 64位oracle 11g(11.1)每天都用oracle.用toad for oracle .电脑固定IP.未更改任何配置信息.用了几个月,突然出现了 ...
- 一些web编程能用到的小知识
1 信用卡验证算法-luhn算法.(in django/utils/checksums.py) 1.从卡号最后一位数字开始,逆向将奇数位(1.3.5等等)相加.2.将偶数位数字相加,但是这里有个麻烦. ...