After compiling the example code, install the graphics driver plugin with the command make install. To start an application using the graphics driver, you can either set the environment variable QWS_DISPLAY and then run the application, or you can just run the application using the -display switch.
Note that this is a minimal example and this driver will not work well with widgets painting themself directly to the screen (e.g. widgets with the Qt::WA_PaintOnScreen window attribute set). Also, the example requires the Linux framebuffer to be set up correctly and with the correct device permissions. For further information, refer to Testing the Linux Framebuffer.
Step 1: Creating a Custom Graphics Driver
Usually, a custom graphics driver is created by subclassing the QScreen class, the base class for implementing screen or graphics drivers in Qt for Embedded Linux. In this example, however, we subclass the QLinuxFbScreen class instead, to ensure that our driver uses the Linux framebuffer.
For our graphics driver, the DBScreen class, we reimplement five functions belonging to QScreen:
In addition to the abovementioned functions, there is a private instance of QPainter and QImage - painter, used for drawing operations on the back buffer, and image, the back buffer itself.
Step 2: Implementing the Back Buffer
The graphics driver must carry out three main functions:
Allocate the back buffer on startup and deallocate it on shutdown.
Draw to the back buffer instead of directly to the screen (which is what QLinuxFbScreen does).
Copy the back buffer to the screen whenever a screen update is done.
Device initializing and shutdown
We first reimplement initDevice() and shutdownDevice().
The initDevice() function initializes the framebuffer. We reimplement this function to enable accelerated drivers to set up the graphic card. For this example, we first call the super class' implementation to set up the Linux framebuffer. If this call returns false, we return false. Otherwise, we initialize the screen cursor with QScreenCursor::initSoftwareCursor() as well as instantiate image and painter. Then, we return true.
bool DBScreen::initDevice()
{
if (!QLinuxFbScreen::initDevice())
return false;
QScreenCursor::initSoftwareCursor();
image = new QImage(deviceWidth(), deviceHeight(), pixelFormat());
painter = new QPainter(image);
return true;
}
The shutdownDevice() function's default implementation only hides the mouse cursor. Hence, we reimplement it to carry out the necessary cleanup before the Qt for Embedded Linux server exits.
Again, we call the super class implementation to shutdown the Linux framebuffer prior to deleting image and painter.
Drawing to the back buffer
We move on to the drawing functions - solidFill() and blit(). In QLinuxFbScreen, these functions draw directly to the Linux framebuffer; but in our driver we reimplement them to draw to the back buffer instead.
void DBScreen::solidFill(const QColor &color, const QRegion ®ion)
{
QVector<QRect> rects = region.rects();
for (int i = 0; i < rects.size(); i++)
painter->fillRect(rects.at(i), color);
}
The solidFill() function is called from exposeRegion() to fill the given region of the screen with the specified color. In this example, we use painter to fill rectangles in image, the back buffer, according to the given region.
The blit() function is also called from exposeRegion() to copy the given QRegion object, region, in the given QImage object, image, to the QPoint object specified by topLeft. Once again we use painter to draw in the back buffer, image.
Displaying the buffer on the screen
The exposeRegion() function is called by the Qt for Embedded Linux server whenever a screen update is required. The given region is the screen region that needs to be updated and changing is is the index into QWSServer::clientWindows() of the window that caused the update.
In our implementation, we first call the super class implementation to ensure that solidFill() and blit() will be called correctly. This causes the changed areas to be updated in the back buffer. We then call the super class' implementation of blit() to copy the updated region from the back buffer into the Linux framebuffer.
Step 3: Creating the Driver Plugin
Qt provides a high level API for writing Qt extentions. One of the plugin base classes provided is QScreenDriverPlugin, which we use in this example to create our screen driver plugin.
class DBScreenDriverPlugin : public QScreenDriverPlugin
{
public:
DBScreenDriverPlugin();
QScreen* create(const QString& key, int displayId);
QStringList keys () const;
};
There are only two functions to reimplement:
create() - creates a driver matching the given key
keys() - returns a list of valid keys representing the drivers supported by the plugin
QScreen* DBScreenDriverPlugin::create(const QString& key, int displayId)
{
if (key.toLower() != "dbscreen")
return 0;
return new DBScreen(displayId);
}
QStringList DBScreenDriverPlugin::keys() const
{
return QStringList() << "dbscreen";
}
Our plugin will only support one driver, dbscreen.
Vous souhaitez rejoindre la rédaction ou proposer un tutoriel, une traduction, une question... ? Postez dans le forum Contribuez ou contactez-nous par MP ou par email (voir en bas de page).
Qt dans le magazine
Cette page est une traduction d'une page de la documentation de Qt, écrite par Nokia Corporation and/or its subsidiary(-ies). Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Nokia.
Vous avez déniché une erreur ? Un bug ? Une redirection cassée ? Ou tout autre problème, quel qu'il soit ? Ou bien vous désirez participer à ce projet de traduction ? N'hésitez pas à nous contacter
ou par MP !