QT做的界面如何与C语言写的中间层高效的进行交互?

jiamianshiye 2014-06-24 06:27:52
运行平台:ARM Linux
界面软件:QT
中间层代码:Linux C

目前我在做一个嵌入式软件,其中需要用到QT来做一个控制界面,其中由于平台缘故,大部分东西需要C来做。这时候我的想法是将界面、C业务层都分开来进行做,将C写的代码编译成库,提供接口给QT调用。但是由于缺乏开发经验,在工作中发现一些问题。
1.当程序运行以后,设备需要从外界传感器获取,交由C业务层处理,将处理结果显示到QT界面上。但是该如何及时的把C的处理结果传给QT界面上呢?
PS:目前我的想法是在C层定义一个结构体,如果有数据需要发送,就往这个结构体填充数据,并将此结构体标记为有效,同时向QT提供一个访问此结构体的函数fun()。 在QT上,另开一个线程循环调用fun() 来获取此数据。但是我感觉这样做效率不高,另外如果需要提交的数据类型太多的话,写代码会稍微麻烦点。

先在这里感谢大家,请大神们多多提出宝贵的建议。
...全文
881 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiamianshiye 2014-06-30
  • 打赏
  • 举报
回复 1
在头文件自定义类,基类为QEvent; 自定义发送事件类,基类为QCoreApplication。

class customEvent : public QEvent
{
public:
    static const QEvent::Type MyEventType;
    customEvent():QEvent(customEvent::MyEventType){
        qDebug()<<"construct customEvent MyEventType is "<<MyEventType;
    }
};
class MySender:public QCoreApplication
{
public:
    MySender(int argc, char *argv[]):QCoreApplication(argc, argv) {}
    bool notify(QObject *r, QEvent *e);
    static bool sendEvent(QObject *r, QEvent *e);
    static void postEvent(QObject *receiver, QEvent *event);
};
在。cpp文件初始化类。

const QEvent::Type customEvent::MyEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User+100);

bool MySender::notify(QObject *r, QEvent *e)
{
    qDebug()<<"notify got event MyEventType !\n";
    if(e->type() == customEvent::MyEventType){
        qDebug()<<"MyEventType is coming!\n";
        //return false;
    }
    return QCoreApplication::notify(r, e);
}

bool MySender::sendEvent(QObject *r, QEvent *e)
{
    qDebug()<<"sendEvent got event MyEventType !";
    qDebug()<<"e->type() == "<<e->type();
    qDebug()<<"MyEventType is "<<customEvent::MyEventType;
    if(e->type() == customEvent::MyEventType){
        qDebug()<<"MyEventType is coming!\n";
        //return false;
    }
    return QCoreApplication::sendEvent(r, e);
}

void MySender::postEvent(QObject *r, QEvent *e)
{
    qDebug()<<"postEvent got event MyEventType!\n";
    if(e->type() == customEvent::MyEventType){
        qDebug()<<"MyEventType is coming!\n";
        //return false;
    }
    QCoreApplication::postEvent(r, e);
}
下面是main.cpp内容。

class MyArmy:public QObject
{
public:
    MyArmy() {}
    void MyEventHandler(QEvent *e);
    bool event(QEvent *e);
};
//
class MyWatcher:public QObject
{
public:
    MyWatcher() {}
    bool eventFilter(QObject *r, QEvent *e);
};

MySender *psender;
MyArmy army;
customEvent customE;
MyWatcher wathcer;

extern "C" {
    void notifyGUI()
    {
        //QCoreApplication::postEvent(&army, &customE);
        //QCoreApplication::sendEvent(&army, &customE);
        //psender->notify(&army, &customE);
        psender->sendEvent(&army, &customE);
        //psender->postEvent(&army, new customEvent);

    }
}
int main(int argc, char *argv[])
{
    //QCoreApplication a(argc, argv);
    MySender sender(argc, argv);
    psender = &sender;
//    MyArmy army;
//    customEvent customE(MyEventType);
//    MyWatcher wathcer;

    registerNotifyFunction(notifyGUI);
    army.installEventFilter(&wathcer);

    //sender.notify(&army, &customE);

    //sender.sendEvent(&army, &customE);
    //sender.postEvent(&army, &customE);

    return sender.exec();

    //return a.exec();
}


void MyArmy::MyEventHandler(QEvent *e)
{
    qDebug()<<"Event being handled!";
    e->accept();
}

bool MyArmy::event(QEvent *e)
{
    if(e->type() == customEvent::MyEventType){
        qDebug()<<"event is MyEventType";
        this->MyEventHandler(e);
        if(e->isAccepted()){
            qDebug()<<"The event is handled!";
            qDebug()<<"e->type() == "<<e->type();

            return true;
        }
    }
    return QObject::event(e);
}


bool MyWatcher::eventFilter(QObject *r, QEvent *e)
{
    if(e->type() == customEvent::MyEventType){
        qDebug()<<"I DO NOT WANNA FILTER";
        //return false;
    }
    return QObject::eventFilter(r, e);
}
其中,自定义事件是从网上搜的例子。详细内容参考:http://blog.csdn.net/michealtx/article/details/6866094。多谢原作者。 QT引用的C库代码:

typedef void (*c_NotifyFn)();
void registerNotifyFunction(c_NotifyFn fn);
c_NotifyFn c_fun;
void *thr_fun()
{
    sleep(3);
    c_fun();
    return NULL;
}

int createthread()
{
    int ret;
    pthread_t pid;
    ret = pthread_create(&pid, NULL, thr_fun, NULL);
    if(ret != 0){
        printf("Create pthread failed!\n");
        return -1;
    }
    return 0;
}

void registerNotifyFunction(c_NotifyFn fn)
{
    c_fun = fn;
    createthread();
}
多谢版主给的意见。
jiamianshiye 2014-06-25
  • 打赏
  • 举报
回复
引用 1 楼 foruok 的回复:
应该通知机制,而不是轮询。 我的建议是使用 Qt 的事件机制,在C业务层,使用 QCoreApplication::postEvent() 来发送事件给 Qt GUI 。因为 C不能访问 Qt 的这些函数,可以封装一个 C函数,在初始化 C 业务层时传递给 C 业务层。比如封装下面的函数:
extern "C" {
    void notifyGUI()
    {
        QCoreApplication::postEvent(g_ui, new YourEvent());
    }
}
然后注册给C业务层。 首先 C 层要提供一个注册函数,如下:
typedef void (*NotifyFn)();
void registerNotifyFunction(NotifyFn fn);
你在 registerNotifyFunctioin 中保存传入的fn,在合适的地方调用就行了。 而在 Qt 代码中这么加一句:
registerNotifyFunction(notifyGUI);
最后你需要自定义事件 YourEvent ,重写 QObject::event() 函数来处理。 OK,大功告成。
多谢版主回复。对于事件通知我不太熟悉,需要查点资料才能继续解决。出来结果以后我会跟帖回复,并附上代码。
foruok 2014-06-25
  • 打赏
  • 举报
回复 1
应该通知机制,而不是轮询。 我的建议是使用 Qt 的事件机制,在C业务层,使用 QCoreApplication::postEvent() 来发送事件给 Qt GUI 。因为 C不能访问 Qt 的这些函数,可以封装一个 C函数,在初始化 C 业务层时传递给 C 业务层。比如封装下面的函数:
extern "C" {
    void notifyGUI()
    {
        QCoreApplication::postEvent(g_ui, new YourEvent());
    }
}
然后注册给C业务层。 首先 C 层要提供一个注册函数,如下:
typedef void (*NotifyFn)();
void registerNotifyFunction(NotifyFn fn);
你在 registerNotifyFunctioin 中保存传入的fn,在合适的地方调用就行了。 而在 Qt 代码中这么加一句:
registerNotifyFunction(notifyGUI);
最后你需要自定义事件 YourEvent ,重写 QObject::event() 函数来处理。 OK,大功告成。
xiaoxiaokun888 2014-06-25
  • 打赏
  • 举报
回复 1
回调函数!!

16,818

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧