2010-10-08 12 views
13

Qt4, QtCreatorQt4 ¿Cómo dibujar dentro de un widget?

estoy tratando de dibujar dentro de Widget:

void Widget::on_pushButton_clicked() 
{ 
    QPainter painter; 

    painter.begin(ui->label); 

    QRectF rectangle(10.0, 20.0, 80.0, 60.0); 
    int startAngle = 30 * 16; 
    int spanAngle = 120 * 16; 
    painter.drawArc(rectangle, startAngle, spanAngle); 

    painter.end(); 
} 

Pero cuando se presiona el botón no pasa nada.

¿Cómo hacer esto de manera correcta?

Respuesta

21

Tiene que anular paintEvent() y pintar allí. Realmente no necesita begin() y end(). Declarar el pintor con

QPainter painter(this); 

El constructor se encargará de begin() y end() se llamará cuando el objeto painter sale del ámbito y se destruye.

Tampoco necesitará el evento de clic para activar la pintura. paintEvent() se llamará siempre que el widget necesite dibujarse a sí mismo. Puede usar el botón de clic para alternar un valor booleano que comprueba el paintEvent() para determinar si debe mostrar el rectángulo o el arco. Solo asegúrese de llamar al update() después de alternar la variable.

void Widget::on_pushButton_clicked() 
{ 
    drawShapes = !drawShapes; 
    update(); 
} 

void Widget::paintEvent(QPaintEvent *) 
{ 
    QPainter painter(this); 

    if(drawShapes) 
    { 
     QRectF rectangle(10.0, 20.0, 80.0, 60.0); 
     int startAngle = 30 * 16; 
     int spanAngle = 120 * 16; 
     painter.drawArc(rectangle, startAngle, spanAngle); 
    } 
} 

ACTUALIZACIÓN:

Para evitar tener que reemplazar el paintEvent() de un widget, se puede utilizar un QLabel y asignar un mapa de píxeles a ella y pintar a eso. Nota: Por lo que puedo decir, tendrá que establecer el mapa de píxeles cada vez que lo modifique.

void MainForm::slot_buttonClick() 
{ 
    QPixmap pixmap(100,100); 
    pixmap.fill(QColor("transparent")); 

    QPainter painter(&pixmap); 
    painter.setBrush(QBrush(Qt::black)); 
    painter.drawRect(10, 10, 100, 100); 

    label.setPixmap(pixmap); 
} 
+0

¿Hay alguna manera de pintar sin anular? ¿O hay algún componente sobre el que pueda dibujar sin ningún evento, como TImage o TForm o cualquier otro componente que contenga TCanvas en VCL (Delphi)? (En Delphi podría escribir Form1.Canvas.Circle (...) siempre que lo necesite, no solo dentro del evento onpaint) – Astronavigator

+0

Nunca he intentado dibujar en un widget con código externo al widget, pero QWidget hereda PaintDevice por lo que debería ser posible. –

+0

Scratch that, from the docs for QPainter .. "Advertencia: cuando paintdevice es un widget, QPainter solo se puede usar dentro de una función paintEvent() o en una función llamada por paintEvent(); a menos que el Qt :: WA_PaintOutsidePaintEvent El atributo widget está configurado. En Mac OS X y Windows, solo puedes pintar en una función paintEvent() independientemente de la configuración de este atributo. " –

0

Si sobrescribe la pintura método descrito por Arnold Spence, debe llamar paintEvent de los padres o terminar con un widget que sólo muestra el rectángulo en un fondo blanco.

Cuestiones relacionadas