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.0\qtbase\src\plugins\platforms\linuxfb"
具体修改参考如下,手残党直接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

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

posted @ 2020-01-14 17:19  刘-皇叔  阅读(1207)  评论(0编辑  收藏  举报