我正在開發一個測試工具以從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;
}