在qt界面上的一些按钮对应的实现功能较为复杂,往往要启用另一进程或线程实现。要启动子进程往往通过进程进程间通信实现,最方便的是管道文件写与读;要启动线程的话有时需要把主线程的参数传给子线程,qt库中的QThreadPool::globalInstance()解决了这个问题。
1. 进程间通信
首先要在qt工程中定义枚举变量
typedef enum QtInterface_Command {
QtInterface_Play,
QtInterface_Pause,
QtInterface_Stop,
QtInterface_Inc,
QtInterface_Dec,
QtInterface_Hide,
//add
QtInterface_Replay,// arg:filename 6
QtInterface_ReplayExit,// 7
QtInterface_Record,// 8
QtInterface_Preview,// 9
//
QtInterface_Detect,//
QtInterface_Distance,//
QtInterface_FocusInc,//
QtInterface_FocusDec,//
QtInterface_FocusRel,//
QtInterface_ResizeInc,// arg:1,2,3,4
QtInterface_ResizeDec,
QtInterface_Invalid,
} QtInterface_Command;
然后定义一个文件中写入字符的函数,写入的值为枚举结构体的某个值
void MessageServer::sendCmd(QtInterface_Command cmd)
{
if ((cmd >= QtInterface_Play) || (cmd < QtInterface_Invalid )) {
/* Send command via pipe */
fputc(cmd, m_fpCmd);
printf(" CMD: %d F: %s L: %d\n",cmd,__FILE__,__LINE__);
}
else {
qFatal("Bad command to send\n");
exit(EXIT_FAILURE);
}
}
然后在主文件中把sendCmd函数作为按钮的槽函数就行了
2. 另起线程
Qt工程中为子线程新建类,类的构造函数的形参接受主线程要传入的参数,并在run函数中调用要实现的focus_set函数。
FocusMngTask::FocusMngTask(FOCUS_OP_E oper)
{
oper_flag=oper;
qDebug() << "FocusMngTask from thread" << QThread::currentThread();
}
int FocusMngTask::gpio_io_ctrl(int num_gpio,int i)
{
int fd;
KD_GPIO_S sGpio;
fd = open(KD_DEV_GPIO, O_RDWR);
if (fd < 0)
{
fprintf(stderr, "open <%s> error %s\n", KD_DEV_GPIO, strerror(errno));
return -1;
}
sGpio.gio_num = num_gpio;
sGpio.val = i;
write(fd,&sGpio,sizeof(KD_GPIO_S));
printf("TIGLE_PORT %d %d\n",sGpio.gio_num, sGpio.val);
close(fd);
return 0;
}
int FocusMngTask::focus_set(FOCUS_OP_E oper)
{
int ret ,ret1;
if(oper == FOCUS_OP_INC)
{
ret = gpio_io_ctrl(FOCUS_GPIO23,0);
ret1 = gpio_io_ctrl(FOCUS_GPIO24,1);
if(ret != 0 || ret1 != 0)
return -1;
}
else if(oper == FOCUS_OP_DEC)
{
ret = gpio_io_ctrl(FOCUS_GPIO23,1);
ret1 = gpio_io_ctrl(FOCUS_GPIO24,0);
if(ret != 0 || ret1 != 0)
return -1;
}
else if(oper == FOCUS_OP_REL)
{
ret = gpio_io_ctrl(FOCUS_GPIO23,0);
ret1 = gpio_io_ctrl(FOCUS_GPIO24,0);
if(ret != 0 || ret1 != 0)
return -1;
}
else
return -1;
return 0;
}
void FocusMngTask::run()
{
focus_set(oper_flag);
qDebug() << "FocusMngTask from thread" << QThread::currentThread();
}
主文件中定义一个函数,这个函数作用是使用线程池启动子线程
void kedun::setFocus(FOCUS_OP_E oper)
{
FocusMngTask *focusMng = new FocusMngTask(oper);
QThreadPool::globalInstance()->start(focusMng);
return ;
}
然后在主文件中把setFocus函数作为按钮的槽函数就行了