版本介紹
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
之后就可以看到旋轉之后的界面。