我正在开发一个测试工具以从PC并行端口生成波形。这个工具被设计用于生成任意波形模式,其定时精度为ms,所以我使用Lua脚本来定义波形模式,当用户单击[Start]按钮时,GUI启动新的QThread来运行脚本。来自Lua脚本的nanosleep()调用暂停QT GUI线程
为lua的以下三个功能被实现为C++全局函数:
- PWRITE:将数据写入到并行端口。
- msleep:等待某个ms(使用nanosleep()实现)
- print:覆盖Lua的默认打印函数,这个函数会将消息附加到一个QTextEdit控件。
当调用pwrite时,写入的数据存储在全局变量中,然后以20ms的间隔更新GUI以更新GUI上的并行端口数据。 (这种20ms的间隔刷新并不是一个好的设计,但是当数据改变时,我还没有弄清楚如何使用信号来更新GUI)。
该工具现在基本可以使用。波形输出没有问题,但并行端口数据更新有一些问题:
当Lua调用msleep时,GUI线程停止,并行端口数据仅在msleep结束后更新。
所以我的问题是:
如何实现睡眠方法,以便它不会停止更新的GUI线程?
如何实现pwrite,以便在写入数据更改时,GUI可以接收信号以更新并行端口数据?
程序GUI下面的链接:
相关的代码:
/* common.cpp file */
int L_MSleep(lua_State* l)
{
int milisec=0;
struct timespec req={0, 0};
time_t sec;
milisec=luaL_optint(l,1,0); // obtain parameter
if (milisec==0)
return 0;
sec=(int)(milisec/1000);
milisec=milisec-(sec*1000);
req.tv_sec=sec;
req.tv_nsec=milisec*1000000L;
while(nanosleep(&req,&req)==-1)
continue;
return 1;
}
/* LuaRunner.cpp file */
LuaRunner::LuaRunner(QObject *parent) :
QThread(parent)
{
runlua = false;
}
void LuaRunner::run()
{
QString err = "";
runlua = true;
LUA_RunScript(this->ff, err);
runlua = false;
if(err != "")
{
emit errorMessage(err);
}
}
int LuaRunner::LUA_RunScript(QString ff, QString &err)
{
L = lua_open();
luaL_openlibs(L);
if (luaL_loadfile(L, ff.toAscii()) || lua_pcall(L, 0, 0, 0))
{
err = QString(lua_tostring(L, -1));
return -1;
}
lua_register(L, "ssleep", L_SSleep);
lua_register(L, "msleep", L_MSleep);
lua_register(L, "pwrite", L_PortWrite);
lua_register(L, "print", L_Log);
lua_getglobal(L, "dotest");
if (!lua_isfunction(L, -1))
{
err = QString("Test function(dotest) should be a function");
return -1;
}
if(lua_pcall(L, 0, 0, 0))
{
err = QString(lua_tostring(L, -1));
return -1;
}
lua_close(L);
return 0;
}