嵌入式QT界面截图模块设计

前言

在嵌入式仪器产品中,经常需要截取仪器界面图片,为相关技术或说明书等相关文档提供原材料;而使用命令行模式截屏的方式只适用于开发人员,针对这种情况便设计了该模块嵌入到仪器界面代码中,可完美解决该问题。

设计需求

在仪器上插入键盘,按下指定按键后可截下仪器当前界面(保存图片名为依次递增数字),且截屏不受界面限制,不管是否有弹窗或子界面等。按下第二个键可实现截图切换保存路劲(路径名最后数字+1),且图片名复位为从1开始递增。

设计思路

1、模块类继承QObject,并重写eventFilter(QObject *obj, QEvent *event)函数;
2、识别功能按钮按下的事件,并运行截图程序;
3、截图程序,使用gsnp程序+输入参数方式实现(嵌入式linux下比较常见),当然也可以使用qt自带的QScreen类或其他众多方式保存截取。
4、安装事件过滤器,使用void installEventFilter(QObject *)函数安装。

模块代码

h文件

class SreenCapture : public QObject
{
    Q_OBJECT
public:
    SreenCapture(){}
    ~SreenCapture(){}
    bool eventFilter(QObject *obj, QEvent *event);
};

cpp文件

bool SreenCapture::eventFilter(QObject *obj, QEvent *event)
{
    static QDateTime lastTime = QDateTime::currentDateTime();
    if(event->type() == QEvent::KeyPress)
    {
        int timeCount = lastTime.secsTo(QDateTime::currentDateTime());
        if(timeCount < 1)
            return QObject::eventFilter(obj,event);
        //qDebug()<<Q_FUNC_INFO<<"time count:"<<timeCount;
        QKeyEvent *key=static_cast<QKeyEvent *>(event);
        static int imgCount = 1,pathCount = 1;
        if(key->key() == Qt::Key_F4)
        {
            imgCount = 0;
            pathCount++;
            if(pathCount > 100)
                pathCount = 1;
        }
        if(key->key() == Qt::Key_F1)
        {
            QDir mntDir("/udisk");
            if (!mntDir.exists())       //判断U盘是否插入
                MessageBoxInstance::GetInstance()->warning(tr("提示"),tr("未识别到USB设备!"), 1,0);
            else
            {
                QString imgPath = QString("/udisk/screen%1").arg(pathCount);
                QDir buff(imgPath);
                if(!buff.exists())
                    system("mkdir /udisk/screen");
                imgPath += "/"+ QString::number(++imgCount) + ".jpg";
                QString strCMD = QString("gsnap %1 /dev/fb0").arg(imgPath);

                system(strCMD.toLatin1());
                qDebug()<<tr("out img: ")+ imgPath;

                //截图程序运行结束后添加提示(这里使用U盘图标闪烁一下表示截图结束)
                StatusBarInstance::GetInstance()->SetUsbConnected(0);
                for(int i = 0;i < 300;i ++)
                {
                    usleep(1000);
                    qApp->processEvents();
                }
                StatusBarInstance::GetInstance()->SetUsbConnected(1);
            }
        }
        lastTime = QDateTime::currentDateTime();      //记录最后一次截图时间
    }
    return QObject::eventFilter(obj,event);
}

使用方法

demo代码

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    SreenCapture *p = new SreenCapture();
    a.installEventFilter(p);
    return a.exec();
}

从demo中没找到MainWindow或其他类的实现,所以该方式可实现无界面运行,即可独立一个程序执行,然后检测按键截取其他进程执行的界面。

注意

本模块SreenCapture 类的实现方式过于简单,其中只有一个虚函数,很多人就喜欢把他写在类中实现(默认为内联函数),这里编译器会报错误。因为类中如果有虚函数,那么至少要有一个函数在cpp文件中实现,否则编译的时候不会为该类创建虚函数表,从而会报undefine vtable的错误。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值