Basically, I want to know why the combination of text alignment flags and setPageSize
doesn't end up with text centered in the display.
The following program does nearly exactly what I want, except that the text ends up centered only horizontally.
#include <QApplication>
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsTextItem>
#include <QTextDocument>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow *mainWindow = new QMainWindow(0, Qt::FramelessWindowHint);
QGraphicsView view;
view.setAlignment(Qt::AlignLeft | Qt::AlignBottom);
view.setFrameStyle(0);
view.setBackgroundBrush(QBrush(QColor(Qt::black)));
mainWindow->setCentralWidget(&view);
QGraphicsScene scene(0, 0, 640, 480);
QGraphicsTextItem textItem;
textItem.setTextWidth(640);
textItem.document()->setPageSize(QSizeF(640, 480));
textItem.document()->setDocumentMargin(0);
textItem.document()->setDefaultTextOption(QTextOption(Qt::AlignCenter | Qt::AlignVCenter));
textItem.setDefaultTextColor(QColor(Qt::white));
textItem.setFont(QFont("monospace", 18, 63));
textItem.setHtml("Center me!");
scene.addItem(&textItem);
textItem.setVisible(true);
view.setScene(&scene);
mainWindow->show();
return a.exec();
}
I should also note that this project is constrained to Qt 4.7.1.
How do I align text both horizontally and vertically in the center of a QGraphicsView
using a QGraphicsTextItem
? I'm fine with a stylesheet-based solution as well.
No, it doesn't.
This bug indicates that the QTextDocument
(the underlying text rendering object) specifically does not attempt to vertical alignment. After looking about, most workarounds fall into two categories. For simple (i.e. single-line plain-text) applications, implement a proxy item that renders the text in its overloaded paint
method as so:
class MyProxyGraphicsItem: public QGraphicsItem {
public:
explicit MyProxyGraphicsItem(QString text, QRectF geometry, QGraphicsItem *parent=0) :
QGraphicsItem(parent), text(text), geometry(geometry)
{}
virtual ~MyProxyGraphicsItem() {}
QRectF boundingRect() const { return geometry; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
painter->drawText(geometry, text, Qt::AlignCenter | Qt::AlignVCenter);
}
private:
QRectF geometry;
QString text;
}
For multi-line plain-text or rich-text (HTML), use a QLabel
in stead as follows:
#include <QApplication>
#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsTextItem>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow *mainWindow = new QMainWindow(0, Qt::FramelessWindowHint);
QGraphicsView view;
view.setAlignment(Qt::AlignLeft | Qt::AlignBottom);
view.setFrameStyle(0);
view.setBackgroundBrush(QBrush(QColor(Qt::black)));
mainWindow->setCentralWidget(&view);
QGraphicsScene scene(0, 0, 640, 480);
QLabel label("<div style=\"color:white;\">Center me!</div>");
label.setWordWrap(true);
label.setAlignment(Qt::AlignCenter | Qt::AlignVCenter);
label.setFont(QFont("monospace", 18, 63));
scene.addWidget(&label)->setGeometry(QRectF(0,0,480,640));
view.setScene(&scene);
mainWindow->show();
return a.exec();
}