Ejemplo de diseño gráfico básico
Demuestra cómo crear un diseño gráfico básico.
El ejemplo de diseño gráfico básico muestra cómo utilizar las clases de diseño en QGraphicsView: QGraphicsLinearLayout y QGraphicsGridLayout. Además, muestra cómo escribir su propio elemento de diseño personalizado.

Definición de la clase Window
La clase Window es una subclase de QGraphicsWidget. Tiene un constructor con un QGraphicsWidget parent como parámetro.
class Window : public QGraphicsWidget { Q_OBJECT public: Window(QGraphicsWidget *parent = nullptr); };
Implementación de la clase Window
El constructor de Window instancia un objeto QGraphicsLinearLayout, windowLayout, con orientación vertical. Instanciamos otro objeto QGraphicsLinearLayout, linear, cuyo padre es windowLayout. A continuación, creamos un objeto LayoutItem, item y lo añadimos a linear con la función addItem(). También dotamos a item de un stretchFactor.
QGraphicsLinearLayout *windowLayout = new QGraphicsLinearLayout(Qt::Vertical); QGraphicsLinearLayout *linear = new QGraphicsLinearLayout(windowLayout); LayoutItem *item = new LayoutItem; linear->addItem(item); linear->setStretchFactor(item, 1);
Repetimos el proceso:
- creamos un nuevo
LayoutItem, - añadimos el objeto
linear, y - proporcionamos un factor de estiramiento.
item = new LayoutItem; linear->addItem(item); linear->setStretchFactor(item, 3); windowLayout->addItem(linear);
A continuación, añadimos linear a windowLayout, anidando dos objetos QGraphicsLinearLayout. Además de QGraphicsLinearLayout, también utilizamos un objeto QGraphicsGridLayout, grid, que es una cuadrícula de 4x3 con algunas celdas que se extienden a otras filas.
Creamos siete objetos LayoutItem y los colocamos en grid con la función addItem() como se muestra en el fragmento de código siguiente:
QGraphicsGridLayout *grid = new QGraphicsGridLayout(windowLayout); item = new LayoutItem; grid->addItem(item, 0, 0, 4, 1); item = new LayoutItem; item->setMaximumHeight(item->minimumHeight()); grid->addItem(item, 0, 1, 2, 1, Qt::AlignVCenter); item = new LayoutItem; item->setMaximumHeight(item->minimumHeight()); grid->addItem(item, 2, 1, 2, 1, Qt::AlignVCenter); item = new LayoutItem; grid->addItem(item, 0, 2); item = new LayoutItem; grid->addItem(item, 1, 2); item = new LayoutItem; grid->addItem(item, 2, 2); item = new LayoutItem; grid->addItem(item, 3, 2); windowLayout->addItem(grid);
El primer elemento que añadimos a grid se coloca en la celda superior izquierda, abarcando cuatro filas. Los dos elementos siguientes se colocan en la segunda columna y abarcan dos filas. Los elementos maximumHeight() y minimumHeight() son iguales para que no se expandan verticalmente. Como resultado, estos elementos no cabrán verticalmente en sus celdas. Por lo tanto, especificamos que deben alinearse verticalmente en el centro de la celda utilizando Qt::AlignVCenter.
Por último, el propio grid se añade a windowLayout. A diferencia de QGridLayout::addItem(), QGraphicsGridLayout::addItem() requiere una fila y una columna para su argumento, especificando en qué celda debe colocarse el elemento. Además, si se omiten los argumentos rowSpan y columnSpan, por defecto serán 1.
Tenga en cuenta que no especificamos un padre para cada LayoutItem que construimos, ya que todos estos elementos se añadirán a windowLayout. Cuando añadimos un elemento a un diseño, se reparentará automáticamente al widget en el que está instalado el diseño.
setLayout(windowLayout);
setWindowTitle(tr("Basic Graphics Layouts Example"));Ahora que hemos configurado grid y lo hemos añadido a windowLayout, instalamos windowLayout en el objeto ventana utilizando QGraphicsWidget::setLayout() y establecemos el título de la ventana.
Definición de la clase LayoutItem
La clase LayoutItem es una subclase de QGraphicsLayoutItem y QGraphicsItem. Tiene un constructor, un destructor y algunas reimplementaciones necesarias. Como hereda de QGraphicsLayoutItem debe reimplementar {QGraphicsLayoutItem::setGeometry()}{setGeometry()} y {QGraphicsLayoutItem::sizeHint()}{sizeHint()}. Además hereda de QGraphicsItem, por lo que debe reimplementar {QGraphicsItem::boundingRect()}{boundingRect()} y {QGraphicsItem::paint()}{paint()}.
class LayoutItem : public QGraphicsLayoutItem, public QGraphicsItem { public: LayoutItem(QGraphicsItem *parent = nullptr); // Inherited from QGraphicsLayoutItem void setGeometry(const QRectF &geom) override; QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const override; // Inherited from QGraphicsItem QRectF boundingRect() const override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override; private: QPixmap m_pix; };
La clase LayoutItem también tiene una instancia privada de QPixmap, m_pix.
Implementación de la clase LayoutItem
En el constructor de LayoutItem, m_pix es instanciado y la imagen block.png es cargada en él.
LayoutItem::LayoutItem(QGraphicsItem *parent) : QGraphicsLayoutItem(), QGraphicsItem(parent), m_pix(QPixmap(QLatin1String(":/images/block.png"))) { setGraphicsItem(this); }
Utilizamos la macro Q_UNUSED() para evitar que el compilador genere advertencias sobre parámetros no utilizados.
void LayoutItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(widget); Q_UNUSED(option); QRectF frame(QPointF(0, 0), geometry().size()); const QSize pmSize = m_pix.size(); QGradientStops stops;
La idea detrás de la función paint() es pintar el rectángulo de fondo y luego pintar un rectángulo alrededor del pixmap.
// paint a background rect (with gradient) QLinearGradient gradient(frame.topLeft(), frame.topLeft() + QPointF(200,200)); stops << QGradientStop(0.0, QColor(60, 60, 60)); stops << QGradientStop(frame.height() / 2 / frame.height(), QColor(102, 176, 54)); //stops << QGradientStop(((frame.height() + h)/2 )/frame.height(), QColor(157, 195, 55)); stops << QGradientStop(1.0, QColor(215, 215, 215)); gradient.setStops(stops); painter->setBrush(QBrush(gradient)); painter->drawRoundedRect(frame, 10.0, 10.0); // paint a rect around the pixmap (with gradient) QPointF pixpos = frame.center() - (QPointF(pmSize.width(), pmSize.height()) / 2); QRectF innerFrame(pixpos, pmSize); innerFrame.adjust(-4, -4, 4, 4); gradient.setStart(innerFrame.topLeft()); gradient.setFinalStop(innerFrame.bottomRight()); stops.clear(); stops << QGradientStop(0.0, QColor(215, 255, 200)); stops << QGradientStop(0.5, QColor(102, 176, 54)); stops << QGradientStop(1.0, QColor(0, 0, 0)); gradient.setStops(stops); painter->setBrush(QBrush(gradient)); painter->drawRoundedRect(innerFrame, 10.0, 10.0); painter->drawPixmap(pixpos, m_pix); }
La reimplementación de boundingRect() fijará la esquina superior izquierda en (0,0), y el tamaño de la misma será el tamaño de los elementos del layout geometry(). Esta es el área dentro de la cual pintamos.
La reimplementación de setGeometry() simplemente llama a la implementación de su clase base. Sin embargo, como esto cambiará el boundingRect también debemos llamar a prepareGeometryChange(). Por último, movemos el elemento según geom.topLeft().
void LayoutItem::setGeometry(const QRectF &geom) { prepareGeometryChange(); QGraphicsLayoutItem::setGeometry(geom); setPos(geom.topLeft()); }
Como no queremos que el tamaño del elemento sea menor que el pixmap, debemos asegurarnos de que devolvemos una sugerencia de tamaño mayor que m_pix. También añadimos algo de espacio extra alrededor para los bordes que pintaremos más tarde. Alternativamente, puedes escalar el pixmap para evitar que el elemento sea más pequeño que el pixmap. El tamaño preferido es el mismo que la sugerencia de tamaño mínimo, mientras que establecemos el máximo para que sea un valor grande
QSizeF LayoutItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const { switch (which) { case Qt::MinimumSize: case Qt::PreferredSize: // Do not allow a size smaller than the pixmap with two frames around it. return m_pix.size() + QSize(12, 12); case Qt::MaximumSize: return QSizeF(1000,1000); default: break; } return constraint; }
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.