1、方式一:

#include "mainwindow.h"
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w_ui;QGraphicsScene *scene = new QGraphicsScene;QGraphicsProxyWidget *w = scene->addWidget(&w_ui);w->setRotation(90);QGraphicsView *view = new QGraphicsView(scene);view->show();return a.exec();
}

2、方式二:针对 linuxfb

(1) 修改linuxfb/qlinuxfbscreen.h,如下所示:

class QLinuxFbScreen : public QFbScreen
{Q_OBJECT
public:QLinuxFbScreen(const QStringList &args);~QLinuxFbScreen();bool initialize();QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;QRegion doRedraw() Q_DECL_OVERRIDE;private:QStringList mArgs;int mFbFd;int mTtyFd;// add by immortal startint mRotation;// add by immortal endQImage mFbScreenImage;int mBytesPerLine;int mOldTtyMode;struct {uchar *data;int offset, size;} mMmap;QPainter *mBlitter;
};

(2) 修改linuxfb/qlinuxfbscreen.cpp,如下所示:

QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)//   : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0)  // modify by immortal: mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0),mRotation(0)
{mMmap.data = 0;
}QLinuxFbScreen::~QLinuxFbScreen()
{if (mFbFd != -1) {if (mMmap.data)munmap(mMmap.data - mMmap.offset, mMmap.size);close(mFbFd);}if (mTtyFd != -1)resetTty(mTtyFd, mOldTtyMode);delete mBlitter;
}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 by immorta startQRegularExpression rotationRx(QLatin1String("rotation=(0|90|180|270)"))// add by immorta endQString fbDevice, ttyDevice;QSize userMmSize;QRect userGeometry;bool doSwitchToGraphicsMode = true;// Parse argumentsforeach (const QString &arg, 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 by immortal startelse if (arg.contains(rotationRx, &match))mRotation = match.captured(1).toInt();// add by immortal 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 devicemFbFd = openFramebufferDevice(fbDevice);if (mFbFd == -1) {qErrnoWarning(errno, "Failed to open framebuffer %s", qPrintable(fbDevice));return false;}// Read the fixed and variable screen informationfb_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 by immortal startQRect originalGeometry = geometry;if( 90 == mRotation  || 270 == mRotation ){int tmp = geometry.width();geometry.setWidth(geometry.height());geometry.setHeight(tmp);}// add by immortal endmGeometry = QRect(QPoint(0, 0), geometry.size());mFormat = determineFormat(vinfo, mDepth);// modify by immortal start//   mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, geometry.size());mPhysicalSize = determinePhysicalSize(vinfo, userMmSize, originalGeometry.size());// modify by immortal end// mmap the framebuffermMmap.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;}// modify by immortal start
//   mMmap.offset = geometry.y() * mBytesPerLine + geometry.x() * mDepth / 8;mMmap.offset = originalGeometry.y() * mBytesPerLine + originalGeometry.x() * mDepth / 8;// modify by immortal endmMmap.data = data + mMmap.offset;QFbScreen::initializeCompositor();// modify by immortal start// mFbScreenImage = QImage(mMmap.data, geometry.width(), geometry.height(), mBytesPerLine, mFormat);mFbScreenImage = QImage(mMmap.data, originalGeometry.width(), originalGeometry.height(), mBytesPerLine, mFormat);// modify by immortal endmCursor = 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);const QVector<QRect> rects = touched.rects();mBlitter->setCompositionMode(QPainter::CompositionMode_Source);for (int i = 0; i < rects.size(); ++i)   // add by immortal 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 by immortal end mBlitter->drawImage(rects[i], *mScreenImage, rects[i]);// add by immortal startmBlitter->resetTransform();// add by immortal end}return touched;
}// grabWindow() grabs "from the screen" not from the backingstores.
// In linuxfb's case it will also include the mouse cursor.
QPixmap QLinuxFbScreen::grabWindow(WId wid, int x, int y, int width, int height) const
{if (!wid) {if (width < 0)width = mFbScreenImage.width() - x;if (height < 0)height = mFbScreenImage.height() - y;return QPixmap::fromImage(mFbScreenImage).copy(x, y, width, height);}QFbWindow *window = windowForId(wid);if (window) {const QRect geom = window->geometry();if (width < 0)width = geom.width() - x;if (height < 0)height = geom.height() - y;QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));rect &= window->geometry();return QPixmap::fromImage(mFbScreenImage).copy(rect);}return QPixmap();
}

2,配置环境变量:

  1. export QT_QPA_PLATFORM=linuxfb:fb=/dev/fb0

  2. 运行程序 ./test -platform linuxfb:fb=/dev/fb0:rotation=90
  3. rotation=90表示旋转90度。不加就默认不旋转

注:方式二完全参考:linuxfb旋转   

方式二旋转之后屏幕原点好像有点问题,不过这个可以通过QT程序去解决。具体解决的原理,我还没有看懂。

非常感谢immortal018。复制过来只是做个备份。

以上两种方式,都测试过,可行。

QT 屏幕旋转的两种方式相关推荐

  1. 全志T507操作小技巧连载1-T507屏幕切换的两种方式

    一.硬件操作平台介绍 FETT507-C核心板集成全志T507四核车规级处理器设计开发,Cortex-A53架构,主频1.5GHz,集成G31 GPU,内存2GB DDR3L,存储8GB eMMC.整 ...

  2. 全志T507屏幕切换的两种方式

    本文介绍了飞凌嵌入式全志T507屏幕切换控制的两种方式. 二.屏幕切换 OKT507-C开发板支持MIPI DSI.HDMI.TV等多种屏幕接口,同时可以进行两个屏幕的同显和异显,可灵活指定HDMI接 ...

  3. Qt开发应用程序的两种方式

    目录 案例:计算圆面积(两种方式实现) 方式一:设计器 Qt Designer实现   (20201015) 方案A:触发按钮事件(_clicked()) 方案B:触发输入编辑框事件(_textCha ...

  4. ios 旋转屏幕试图切换_总结iOS App开发中控制屏幕旋转的几种方式

    在iOS6之前的版本中,通常使用 shouldAutorotateToInterfaceOrientation 来单独控制某个UIViewController的方向,需要哪个viewControlle ...

  5. hdmi 屏幕旋转 树莓派_树莓派屏幕旋转的两种方法

    标题中的两种方法,实际是对应两种情况.之所以存在两种情况,原因在于现在的(2018.2.4)的raspbian之中,存在一个实验性质的openGL驱动,该驱动能够提供更好的图形性能,但是暂时还不稳定. ...

  6. 【Android】android开发---实现屏幕旋转的两种方法

    前言 为实现播放器全屏竖屏切换,还可锁住横屏,解锁后又可以跟随传感器变化. 正文 方法一:通过控制android:screenOrientation属性控制横竖屏 1.使用 SCREEN_ORIENT ...

  7. Android屏幕适配的两种方式

    ScreenHelper github 地址:github.com/bugyun/Scre- 欢迎 star 和 提问. 第一种适配方式 - sw 方式 插件版本: 使用方法 在项目的根 build. ...

  8. iOS开发中禁止屏幕旋转的2种方式

    在AppDelegate.m中添加以下代码: - (UIInterfaceOrientationMask)application:(UIApplication *)application suppor ...

  9. Qt创建线程两种方式的区别

    使用QT创建线程有两种方式,方式A使用moveToThread,方式B是直接继承QThread.差异主要在于方式A的槽函数将会在新线程中运行,而方式B的槽函数在旧线程中运行. 结论如下: PS:旧线程 ...

最新文章

  1. python条件语句-Python3 条件控制
  2. 吐槽知乎现任搜索引擎
  3. 谈一谈CMU导师和学生的互动方式
  4. 在soa工程中使用dubbo的步骤
  5. boost::mp11::mp_max相关用法的测试程序
  6. 基于 vue-cli4+vant 搭建 H5 通用架子(支持微信公众号)
  7. 天空象棋——网站与用户
  8. python创建一个空的dataframe_python - 创建一个空的Pandas DataFrame,然后填充它?
  9. 对instance进行二次封装
  10. 【pytorch】常见的坑汇总
  11. erc20钱包下载_【重要公告】VNT Chain主网钱包使用指南
  12. Android个人日记本开发背景,毕业设计(论文)-手机app移动开发论文个人心情日记本的设计实现 .doc...
  13. svchost.exe小记
  14. 迪杰斯特拉和弗洛伊德算法
  15. 3天完成Open CPU开发!7天完成Costdown!满足客户对成本、功耗、安全性等方面的需求!
  16. 【COCOS2DX-游戏开发之七】添加启动数字输入法的功能
  17. 3D游戏引擎入门课程——场景管理
  18. Mac如何保护苹果账户的安全?保护 Apple ID 帐户的技巧分享
  19. 认知升级|系列1|富人思维
  20. 前端数组如何传到后台

热门文章

  1. UI设计的APP标准规范
  2. vue部署后饿了么组件的图片不见了
  3. Win7(老PC)Python环境搭建实战
  4. 国际高性能计算和人工智能咨询委员会公布第五届亚太区 HPC-AI竞赛结果
  5. 《MATLAB 神经网络43个案例分析》:第4章 神经网络遗传算法函数极值寻优——非线性函数极值寻优
  6. 如何创建海外美区Apple ID,并使用支付宝购买Apple Store礼品卡,十分钟学会
  7. Monash call (莫纳什来电) -开篇
  8. 一步一步开发Game服务器(二)登陆2
  9. 计算机网络设备的运行温度,什么是机房温度、湿度标准?
  10. 小米MAX3 线刷兼救砖_解账户锁_纯净刷机包_教程