• QT 海思编程三两事


    版本介绍

    QT的版本为:5.14.0。
    海思型号:3516。

    QT界面无法显示中文

    在 Windows PC 上C盘搜索 .ttf 会出现很多以此为后缀的字体,在这里我选择的是 simkai.ttf。 将其拷贝到板子上, 并且设置环境变量:

    export QT_QPA_FONTDIR=$QT_ROOT/fonts
    

    之后就可以在QT界面上显示中文了。

    QT 界面旋转显示

    为了将界面旋转90度,需要修改QT的源码 "qt-everywhere-src-5.14.0qtbasesrcpluginsplatformslinuxfb"
    具体修改参考如下,手残党直接for you
    qlinuxfbscreen.h

    class QLinuxFbScreen : public QFbScreen
    {
        Q_OBJECT
    public:
        ...... 
    
    private:
        //@ add for rotation
        int mRotation;
        ...... 
    };
    

    qlinuxfbscreen.cpp

    QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
        : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0),mRotation(0)
    {
        mMmap.data = 0;
    }
    
    bool QLinuxFbScreen::initialize()
    {
        QRegularExpression ttyRx(QLatin1String("tty=(.*)"));
        QRegularExpression fbRx(QLatin1String("fb=(.*)"));
        QRegularExpression mmSizeRx(QLatin1String("mmsize=(\d+)x(\d+)"));
        QRegularExpression sizeRx(QLatin1String("size=(\d+)x(\d+)"));
        QRegularExpression offsetRx(QLatin1String("offset=(\d+)x(\d+)"));
    
        //@ add for rotation
        QRegularExpression rotationRx(QLatin1String("rotation=(0|90|180|270)"));
    
        QString fbDevice, ttyDevice;
        QSize userMmSize;
        QRect userGeometry;
        bool doSwitchToGraphicsMode = true;
    
        // Parse arguments
        for (const QString &arg : qAsConst(mArgs)) {
            QRegularExpressionMatch match;
            if (arg == QLatin1String("nographicsmodeswitch"))
                doSwitchToGraphicsMode = false;
            else if (arg.contains(mmSizeRx, &match))
                userMmSize = QSize(match.captured(1).toInt(), match.captured(2).toInt());
            else if (arg.contains(sizeRx, &match))
                userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt()));
            else if (arg.contains(offsetRx, &match))
                userGeometry.setTopLeft(QPoint(match.captured(1).toInt(), match.captured(2).toInt()));
            else if (arg.contains(ttyRx, &match))
                ttyDevice = match.captured(1);
            else if (arg.contains(fbRx, &match))
                fbDevice = match.captured(1);        
            //@ add for rotation start
            else if(arg.contains(rotationRx,&match))
                mRotation = match.captured(1).toInt();
            //@ add for rotation end
    
        }
    
        if (fbDevice.isEmpty()) {
            fbDevice = QLatin1String("/dev/fb0");
            if (!QFile::exists(fbDevice))
                fbDevice = QLatin1String("/dev/graphics/fb0");
            if (!QFile::exists(fbDevice)) {
                qWarning("Unable to figure out framebuffer device. Specify it manually.");
                return false;
            }
        }
    
        // Open the device
        mFbFd = openFramebufferDevice(fbDevice);
        if (mFbFd == -1) {
            qErrnoWarning(errno, "Failed to open framebuffer %s", qPrintable(fbDevice));
            return false;
        }
    
        // Read the fixed and variable screen information
        fb_fix_screeninfo finfo;
        fb_var_screeninfo vinfo;
        memset(&vinfo, 0, sizeof(vinfo));
        memset(&finfo, 0, sizeof(finfo));
    
        if (ioctl(mFbFd, FBIOGET_FSCREENINFO, &finfo) != 0) {
            qErrnoWarning(errno, "Error reading fixed information");
            return false;
        }
    
        if (ioctl(mFbFd, FBIOGET_VSCREENINFO, &vinfo)) {
            qErrnoWarning(errno, "Error reading variable information");
            return false;
        }
    
        mDepth = determineDepth(vinfo);
        mBytesPerLine = finfo.line_length;
        QRect geometry = determineGeometry(vinfo, userGeometry);
    
        //@ add for rotation start
        QRect originalGeometry = geometry;
        if(90 == mRotation || 270 == mRotation)
        {
            int tmp = geometry.width();
            geometry.setWidth(geometry.height());
            geometry.setHeight(tmp);
        }
        //@ add for rotation end
    
        mGeometry = QRect(QPoint(0, 0), geometry.size());
        mFormat = determineFormat(vinfo, mDepth);
        
        //@ add for rotation start
        //mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size());
         mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, originalGeometry.size());
        //@ add for rotation end
    
    
        // mmap the framebuffer
        mMmap.size = finfo.smem_len;
        uchar *data = (unsigned char *)mmap(0, mMmap.size, PROT_READ | PROT_WRITE, MAP_SHARED, mFbFd, 0);
        if ((long)data == -1) {
            qErrnoWarning(errno, "Failed to mmap framebuffer");
            return false;
        }
    
        //@ add for rotation start
        //mMmap.offset = geometry.y() * mBytesPerLine + geometry.x() * mDepth / 8;
        mMmap.offset = originalGeometry.y() * mBytesPerLine + originalGeometry.x() * mDepth / 8;
        //@ add for rotation end
    
        mMmap.data = data + mMmap.offset;
    
        QFbScreen::initializeCompositor();
        //@ add for rotation start
        //mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
        mFbScreenImage = QImage(mMmap.data, originalGeometry.width(), originalGeometry.height(), mBytesPerLine, mFormat);
        //@ add for rotation end
    
        mCursor = new QFbCursor(this);
    
        mTtyFd = openTtyDevice(ttyDevice);
        if (mTtyFd == -1)
            qErrnoWarning(errno, "Failed to open tty");
    
        switchToGraphicsMode(mTtyFd, doSwitchToGraphicsMode, &mOldTtyMode);
        blankScreen(mFbFd, false);
    
        return true;
    }
    
    QRegion QLinuxFbScreen::doRedraw()
    {
        QRegion touched = QFbScreen::doRedraw();
    
        if (touched.isEmpty())
            return touched;
    
        if (!mBlitter)
            mBlitter = new QPainter(&mFbScreenImage);
    
        mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
        for (const QRect &rect : touched)
        {
            //@ add for rotation start
            if(90 == mRotation || 270 == mRotation)
            {
                mBlitter->translate(mGeometry.height()/2,mGeometry.width()/2);
            }
            else if(180 == mRotation)
            {
                mBlitter->translate(mGeometry.width()/2,mGeometry.height()/2);
            }
            if(mRotation != 0)
            {
                mBlitter->rotate(mRotation);
                mBlitter->translate(-mGeometry.width()/2, -mGeometry.height()/2);
            }
            //@ add for rotation end
    
            mBlitter->drawImage(rect, mScreenImage, rect);
    
            //@ add for rotation start
            mBlitter->resetTransform();
            //@ add for rotation end
    
        }
    
        return touched;
    }
    

    修改完成之后重新编译生成 libqlinuxfb.so ,将其替换之前的库文件,并且在程序运行之前进行设置:

    export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0:rotation=90 
    

    或者运行程序时加入参数:

    ./app -platform linuxfb:fb=/dev/fb0:rotatio=90
    

    之后就可以看到旋转之后的界面。

  • 相关阅读:
    SOA架构之限流
    《OD面试》之多线程高并发
    认知升级之第一性原理
    我的第一性原理
    书单收集
    mysql死锁问题解决
    阿里巴巴未来十年使命、愿景和价值观
    python操作Excel模块openpyxl
    qt5--文件操作
    qt5--QPainter绘图
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/12193134.html
Copyright © 2020-2023  润新知