qt5.0 release版终于在2012/12/19出来了
看了下源码,模块化做得很不错,很多东西都从原来的qtbase里抽出来,变成单独模块,依赖关系变得很明确
然后就抽了点时间(到年底了,事情也蛮多的)做了下移植工作
qt5.0可能刚出来,很多移植的东西没加进去,所以如果要移植到自己的开发板上,那就要做点移植的工作了
我的编译选项
./configure -v -prefix /qt5.0 -xplatform linux-mips-g++ -confirm-license -release -shared -opensource -nomake demos -nomake examples \
-qt-sql-sqlite \
-no-openvg \
-no-eglfs
其中-xplatform linux-mips-g++就是交叉编译要找的目录
最原始的代码里是没有linux-mips-g++这个目录的
所以要自己添加
创建linux-mips-g++在qtbase/mkspecs下
然后添加文件qmake.conf
MAKEFILE_GENERATOR = UNIX CONFIG += incremental gdb_dwarf_index QMAKE_INCREMENTAL_STYLE = sublib include(../common/linux.conf) include(../common/gcc-base-unix.conf) include(../common/g++-unix.conf) # modifications to g++.conf QMAKE_CC = mipsel-linux-gcc QMAKE_CXX = mipsel-linux-g++ QMAKE_CFLAGS += -mips32 QMAKE_CXXFLAGS += -mips32 QMAKE_LINK = mipsel-linux-g++ QMAKE_LINK_SHLIB = mipsel-linux-g++ # modifications to linux.conf QMAKE_AR = mipsel-linux-ar cqs QMAKE_OBJCOPY = mipsel-linux-objcopy QMAKE_STRIP = mipsel-linux-strip load(qt_config)
就可以了
然后执行编译选项,然后make,make install就可以了
之后就是重点,写图形插件,就是将qt生成的图片的buffer copy到板子sdk提供的fb接口上
qt5对比qt4对于插件的改动还是蛮大的,至少目录结构改了
qt4是在plugins/gfxdrivers下
qt5则在plugins/platforms下
那么就进入plugins/platforms下
自己创建个目录,写工程文件和继承对应的插件类,进行扩展(看过很多开源代码,大部分都是这种设计模式,一来你增加功能只需要添加代码就可以,二来这种结构在运行时加载,你可以随时切换,大家设计自己的工程时不妨考虑这种设计模式)
1.创建xxx.json文件(xxx就是你自定义命名)
{ "Keys": [ "xxx"] }
2.创建main.cpp
#include <qpa/qplatformintegrationplugin.h> #include "qxxxintegration.h" QT_BEGIN_NAMESPACE class QxxxIntegrationPlugin : public QPlatformIntegrationPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPA.QPlatformIntegrationFactoryInterface.5.1" FILE "bcm.json") public: QPlatformIntegration *create(const QString&, const QStringList&); }; QPlatformIntegration * QxxxIntegrationPlugin::create(const QString& system, const QStringList& paramList) { Q_UNUSED(paramList); if (system.toLower() == "xxx") return new QxxxIntegration(paramList); return 0; } QT_END_NAMESPACE #include "main.moc"
3.qxxxintegration.h(这里和后面都用linuxfb里的例子)
#ifndef QLINUXFBINTEGRATION_H #define QLINUXFBINTEGRATION_H #include <qpa/qplatformintegration.h> QT_BEGIN_NAMESPACE class QLinuxFbIntegrationPrivate; class QAbstractEventDispatcher; class QLinuxFbScreen; class QLinuxFbIntegration : public QPlatformIntegration { public: QLinuxFbIntegration(const QStringList ¶mList); ~QLinuxFbIntegration(); bool hasCapability(QPlatformIntegration::Capability cap) const; QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const; QPlatformWindow *createPlatformWindow(QWindow *window) const; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const; QAbstractEventDispatcher *guiThreadEventDispatcher() const; QList<QPlatformScreen *> screens() const; QPlatformFontDatabase *fontDatabase() const; private: QLinuxFbScreen *m_primaryScreen; QPlatformFontDatabase *m_fontDb; QAbstractEventDispatcher *m_eventDispatcher; }; QT_END_NAMESPACE #endif // QLINUXFBINTEGRATION_H
4.qxxxintegration.cpp
#include "qlinuxfbintegration.h" #include "qlinuxfbscreen.h" #include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h> #include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h> #include <QtPlatformSupport/private/qfbbackingstore_p.h> #include <QtPlatformSupport/private/qfbwindow_p.h> #include <QtPlatformSupport/private/qfbcursor_p.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qpixmap_raster_p.h> QT_BEGIN_NAMESPACE QLinuxFbIntegration::QLinuxFbIntegration(const QStringList ¶mList) : m_fontDb(new QGenericUnixFontDatabase()), m_eventDispatcher(createUnixEventDispatcher()) { QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher); m_primaryScreen = new QLinuxFbScreen; if (m_primaryScreen->initialize(paramList)) screenAdded(m_primaryScreen); } QLinuxFbIntegration::~QLinuxFbIntegration() { delete m_primaryScreen; } bool QLinuxFbIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { case ThreadedPixmaps: return true; default: return QPlatformIntegration::hasCapability(cap); } } QPlatformPixmap *QLinuxFbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const { return new QRasterPlatformPixmap(type); } QPlatformBackingStore *QLinuxFbIntegration::createPlatformBackingStore(QWindow *window) const { return new QFbBackingStore(window); } QPlatformWindow *QLinuxFbIntegration::createPlatformWindow(QWindow *window) const { return new QFbWindow(window); } QAbstractEventDispatcher *QLinuxFbIntegration::guiThreadEventDispatcher() const { return m_eventDispatcher; } QList<QPlatformScreen *> QLinuxFbIntegration::screens() const { QList<QPlatformScreen *> list; list.append(m_primaryScreen); return list; } QPlatformFontDatabase *QLinuxFbIntegration::fontDatabase() const { return m_fontDb; } QT_END_NAMESPACE
5.qxxxscreen.h(这个我针对linuxfbscreen.h删改过的)
#ifndef QLINUXFBSCREEN_H #define QLINUXFBSCREEN_H #include <QtPlatformSupport/private/qfbscreen_p.h> QT_BEGIN_NAMESPACE class QPainter; class QFbCursor; class QLinuxFbScreen : public QFbScreen { Q_OBJECT public: QLinuxFbScreen(); ~QLinuxFbScreen(); bool initialize(const QStringList &args); public slots: QRegion doRedraw(); private: QImage mFbScreenImage; int mBytesPerLine; QPainter *mBlitter; }; QT_END_NAMESPACE #endif // QLINUXFBSCREEN_H
6.qxxxscreen.cpp
#include "qlinuxfbscreen.h" #include <QtPlatformSupport/private/qfbcursor_p.h> #include <QtGui/QPainter> #include <private/qcore_unix_p.h> // overrides QT_OPEN #include <qimage.h> #include <qdebug.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include "bcminterface.h" QT_BEGIN_NAMESPACE #define WIDTH_FB 1440 #define HEIGHT_FB 1080 #define BYTESPERLINE (4 * WIDTH_FB) #define DEPTH_FB (4 * 8) #define DPI (72) #define ROUND_PI ((double)25.4) QLinuxFbScreen::QLinuxFbScreen() : mBlitter(0) { InitBCMInterface(WIDTH_FB, HEIGHT_FB); } QLinuxFbScreen::~QLinuxFbScreen() { delete mBlitter; } static uchar* pBuffer = NULL; static int nSize = 0; bool QLinuxFbScreen::initialize(const QStringList &args) { #if 1 mDepth = DEPTH_FB;//determineDepth(vinfo); mBytesPerLine = BYTESPERLINE;//finfo.line_length; mGeometry = QRect(0, 0, WIDTH_FB, HEIGHT_FB);//determineGeometry(vinfo, userGeometry); mFormat = QImage::Format_ARGB32;//determineFormat(vinfo, mDepth); //printf("[GUM], format: %d, %d, <%s, %s, %d>\n", mFormat, QImage::Format_ARGB32_Premultiplied, __FILE__, __FUNCTION__, __LINE__); mPhysicalSize = QSize(qRound(WIDTH_FB * ROUND_PI / DPI), qRound(HEIGHT_FB * ROUND_PI / DPI));//determinePhysicalSize(vinfo, userMmSize, mGeometry.size()); #endif nSize = (WIDTH_FB * HEIGHT_FB * 4); pBuffer = (uchar*)GetBcmBuffer(&nSize); memset(pBuffer, 0, nSize); QFbScreen::initializeCompositor(); mFbScreenImage = QImage(pBuffer, mGeometry.width(), mGeometry.height(), mBytesPerLine, mFormat); mCursor = new QFbCursor(this); return true; } QRegion QLinuxFbScreen::doRedraw() { QRegion touched = QFbScreen::doRedraw(); if (touched.isEmpty()) { return touched; } if (!mBlitter) mBlitter = new QPainter(&mFbScreenImage); QVector<QRect> rects = touched.rects(); for (int i = 0; i < rects.size(); i++) mBlitter->drawImage(rects[i], *mScreenImage, rects[i]); return touched; } QT_END_NAMESPACE
主要是继承了QFbScreen,要设一下成员变量的值
其中mDepth、mGeometry、mFormat、mPhysicalSize要设一下
然后初始化QFbScreen::initializeCompositor();
mCursor = new QFbCursor(this);
将你sdk上对应fb的指针传给mFbScreenImage对象,就是pBuffer的值,不同sdk有不同的做法,这里就不详说了
最后doredraw是由qt去调,进行绘画
我这里用了test/manual/qlayout作为测试例子
执行qlayout -platform xxx
结果如下