qt5.3 release版终于出来了
看了下源码,模块化做得很不错,很多东西都从原来的qtbase里抽出来,变成单独模块,依赖关系变得很明确
然后就抽了点时间(到年底了,事情也蛮多的)做了下移植工作
qt5.0可能刚出来,很多移植的东西没加进去,所以如果要移植到自己的开发板上,那就要做点移植的工作了
我的编译选项
export PATH=~/work/rtl819x-SDK-v3.4.6.4-full-package/rtl819x/toolchain/rsdk-1.5.5-4181-EB-2.6.30-0.
9.30.3-110225/bin/:$PATH
./configure -v -prefix /qt5.0 -xplatform linux-mips-g++ -confirm-license -release -shared -opensource -nomake tests -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)
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"]
- }
{
"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"
#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
#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
#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
#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
#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