qt5.0移植

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

结果如下

qt5.0移植_第1张图片

你可能感兴趣的:(qt5.0移植)