How to create a QIcon with Qt programmatically

First, create a 32×32 QImage and make it transparent (or whatever background color you need):

QImage img(32, 32, QImage::Format_ARGB32);
img.fill(QColor(0, 0, 0, 0));

I use QImage instead of QPixmap, because the documentation says that QImage is optimized for I/O, e.g. painting, and the first attempts with QPixmap looked like crap. Next, create a QPainter for the QPaintDevice and set some render hints to make it look nice:

QPainter *p = new QPainter(&img);
p->setRenderHint(QPainter::Antialiasing);
p->setRenderHint(QPainter::TextAntialiasing);
p->setRenderHint(QPainter::SmoothPixmapTransform);

QPainter::setBrush() sets the background color for shapes, QPainter::setPen() the foreground color for text:

p->setBrush(QColor(Qt::red));
p->setPen(QColor(Qt::white));

Then select a font the size of our future Icon:

QFont f("courier new");
f.setPixelSize(32);
p->setFont(f);

Now we need some background. White on transparent isn’t really readable, so let’s draw a circle:

p->drawEllipse(img.rect());

Since our QImage is actually a square and not an rectangle, QPainter::drawEllipse will draw a circle. Print the QChar, letter, or whatever:

p->drawText(img.rect(), Qt::AlignCenter, QChar(char));

Now clean up and return the QImage as QIcon:

delete p;
return QIcon(QPixmap::fromImage(img));

The whole shebang can be marveled at here. It looks like this:

Have fun!

KGlobalAccel

This definitely merits a post. While working on my Qt Audio Player (BeetPlayer), I wanted control it via the Media Keys of my Keyboard. Since I’m using KDE on Linux, I quickly found out about KGlobalAccel.

Unfortunately, there’s no decent documentation available. The API docs are kinda useless, and there’s no tutorial available, at least not with my Google foo, so here is how it works:

First and foremost, set QObject::objectName() for the QAction you want to register. It should be unique!

Don’t forget to change your CMake file or your .pro-File if you’re using qmake.

Then register a shortcut with KGlobalAccel::self()->setShortcut() like this:

QAction *muteA = new QAction(QIcon(":/mute.png"), tr("Mute"), this); 
muteA->setObjectName("beetPlayerMute"); 
connect(muteA, SIGNAL(triggered(bool)), this, SLOT(mute(bool))); 
KGlobalAccel::self()->setShortcut(muteA, QList<QKeySequence>() << QKeySequence(Qt::Key_VolumeMute), KGlobalAccel
::Autoloading);

After that launch KDE System Settings->Shortcuts->Global Shortcuts. There should be an entry for your Application. Select it and set the shortcut. Haven’t figured out how a default shortcut, but it doesn’t really matter when it shows up there.