如何使用 Linux 帧缓冲区旋转 Qt5 应用程序?

问题描述 投票:0回答:2

我有一个直接在 Linux 帧缓冲区(无 x-Windows)上运行的嵌入式 Linux 应用程序。 现在我们必须将显示屏物理旋转 180 度。 如何让我的 Qt 应用程序旋转,使其不会出现颠倒? 我看到参考使用以下选项:

 -platform linuxfb:fb=/dev/fb0:rotation:180 

但是,旋转选项似乎被忽略了。

在 Ubuntu 服务器 16.04.6 上使用 Qt 5.9.2

linux qt qt5 ubuntu-16.04 framebuffer
2个回答
5
投票

您可以在应用程序级别处理它。使用 QML 这很容易,但使用 QWidgets 我能想到的最好的办法就是在

QGraphicsScene
上渲染 Widget 并像这样旋转它:

#include "mainwindow.h"
#include <QApplication>

#include <QGraphicsScene>
#include <QGraphicsView>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    QGraphicsScene *scene = new QGraphicsScene();
    QGraphicsView *view = new QGraphicsView();
    view->setGeometry(w.geometry());
    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    scene->addWidget(&w);
    view->setScene(scene);
    view->show();
    view->rotate(180);

    //w.show();

    return a.exec();
}

看起来有点小问题,但你可以尝试一下。

另外,我认为正确的语法是

-platform linuxfb:fb=/dev/fb0:rotation=180
注意
=
而不是
:
编辑:但这对我来说也没有什么区别。


0
投票

这是一个旧线程,但至少对 2024 年的我来说这仍然有用。然而,执行此操作时,我们的 GUI 中最多会收到 4 次 keyPress 事件。可能在事件处理和添加视图和场景中没有正确完成某些事情,从而暴露了它。 无论如何,我们设法使用 BorkedLabs 的解决方案来旋转 GUI:https://borkedlabs.com/blog/2015/06-01-qt5-linuxfb-rotation-for-lcds/ 但我必须修改补丁才能在 QT 5.14.2 中使用

由于我们使用的是 Yocto,我必须在

meta-qt5/recipes-qt/qt5/qtbase/0023-linuxfb_rotation.patch
中添加补丁并修改
meta-qt5/recipes-qt/qt5/qtbase/qtbase_git.bb
以将其包含在其他补丁中。 补丁:

diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index a66c9fa..a5b5f13 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -287,7 +287,7 @@ static void blankScreen(int fd, bool on)
}
QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
- : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0)
+ : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0), mRotation(180)
{
mMmap.data = 0;
}
@@ -313,6 +313,7 @@ bool QLinuxFbScreen::initialize()
QRegularExpression mmSizeRx(QLatin1String("mmsize=(\\d+)x(\\d+)"));
QRegularExpression sizeRx(QLatin1String("size=(\\d+)x(\\d+)"));
QRegularExpression offsetRx(QLatin1String("offset=(\\d+)x(\\d+)"));
+ QRegularExpression rotationRx(QLatin1String("rotation=(0|90|180|270)"));
QString fbDevice, ttyDevice;
QSize userMmSize;
@@ -334,6 +335,8 @@ bool QLinuxFbScreen::initialize()
ttyDevice = match.captured(1);
else if (arg.contains(fbRx, &match))
fbDevice = match.captured(1);
+ else if (arg.contains(rotationRx, &match))
+ mRotation = match.captured(1).toInt();
}
if (fbDevice.isEmpty()) {
@@ -372,10 +375,17 @@ bool QLinuxFbScreen::initialize()
mDepth = determineDepth(vinfo);
mBytesPerLine = finfo.line_length;
QRect geometry = determineGeometry(vinfo, userGeometry);
+ QRect originalGeometry = geometry;
+ if( mRotation == 90 || mRotation == 270 )
+ {
+ int tmp = geometry.width();
+ geometry.setWidth(geometry.height());
+ geometry.setHeight(tmp);
+ }
+
mGeometry = QRect(QPoint(0, 0), geometry.size());
mFormat = determineFormat(vinfo, mDepth);
- mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size());
-
+ mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, originalGeometry.size());
// mmap the framebuffer
mMmap.size = finfo.smem_len;
uchar *data = (unsigned char *)mmap(0, mMmap.size, PROT_READ | PROT_WRITE, MAP_SHARED, mFbFd, 0);
@@ -384,11 +394,11 @@ bool QLinuxFbScreen::initialize()
return false;
}
- mMmap.offset = geometry.y() * mBytesPerLine + geometry.x() * mDepth / 8;
+ mMmap.offset = originalGeometry.y() * mBytesPerLine + originalGeometry.x() * mDepth / 8;
mMmap.data = data + mMmap.offset;
QFbScreen::initializeCompositor();
- mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);
+ mFbScreenImage = QImage(mMmap.data, originalGeometry.width(), originalGeometry.height(), mBytesPerLine, mFormat);
mCursor = new QFbCursor(this);
@@ -414,8 +424,27 @@ QRegion QLinuxFbScreen::doRedraw()
mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
for (const QRect &rect : touched)
+ {
+ if( mRotation == 90 || mRotation == 270 )
+ {
+ mBlitter->translate(mGeometry.height()/2, mGeometry.width()/2);
+ }
+ else if( mRotation == 180 )
+ {
+ mBlitter->translate(mGeometry.width()/2, mGeometry.height()/2);
+ }
+
+ if( mRotation != 0 )
+ {
+ mBlitter->rotate(mRotation);
+ mBlitter->translate(-mGeometry.width()/2, -mGeometry.height()/2);
+ }
+
mBlitter->drawImage(rect, mScreenImage, rect);
+ mBlitter->resetTransform();
+ }
+
return touched;
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
index 1997d46..a34414f 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
@@ -57,6 +57,7 @@ private:
QStringList mArgs;
int mFbFd;
int mTtyFd;
+ int mRotation;
QImage mFbScreenImage;
int mBytesPerLine;
© www.soinside.com 2019 - 2024. All rights reserved.