Qt - draw inside QScrollArea in a QDialog - qt

In Qt5, I have a QDialog window on which I have drawn a circle as follows:
void MyDialog::paintEvent(QPaintEvent *pe)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing,true);
QPen pen(Qt::blue,2);
painter.setPen(pen);
QRect r=QRect(0,0,100,100);
painter.drawEllipse(r);
}
If I draw a larger circle, for example by using QRect(0,0,500,500);, the circle being greater than the dialog window is clipped. So I dragged a QScrollArea onto the the dialog window and decide to draw onto that so that scroll bars are automatically added. The QScrollArea can be accessed using ui->scrollArea.
I changed the above code by setting QPainter painter(ui->scrollArea);. However, nothings appears in the QScrollArea. I read that I need to override the paintEvent of QScrollArea. But I don't know how to do this.
Any help of drawing on the QScrollArea?

Drawing on the QScrollArea is not what you want either because the QScrollArea actually has a viewport widget.
Create another class which inherits QWidget. Override the paintEvent() method and to the painting you mention. Then, add the widget to the scroll area in your dialog.
MyDialog::MyDialog()
{
QScrollArea *pScrl = new QScrollArea(this);
pScrl->setWidget(new MyWidget(pScrl));
... // use a layout to put the scroll area in the dialog
}
To really make it useful you will need to resize the MyWidget instance to the size of the circle that you want to draw.

Related

Graphics errors with QWidgets in a QGraphicsScene

I am trying to have a widget live freely inside a large scrollable panel. When I scroll around the QGraphics view, the child widget does not draw properly— its sub-rectangles will blank out, and the borders (which are rounded) are not blended with the canvas. I have:
QApplication qapp(argc, argv);
QGraphicsView view;
QGraphicsScene scene;
// a simple QWidget with a gridlayout and some child objects:
MyQWidget mywidget(NULL);
scene.addWidget(&mywidget);
view.setScene(&scene);
view.setSceneRect(0,0,1280,1280);
view.show();
view.resize(512,512);
qapp.exec();
I get the same bogus rendering if I use a QGraphicsProxyWidget and scene.addItem() instead.
If instead I parent my custom widget to the QGraphicsView, it renders properly, but then the widget does not seem to be part of the QGraphicsScene, because it doesn't scroll around anymore and remains fixed to the parent window.
What's going on?
Edit: Images of the blanking problem, with MyWidget replaced by QPushButton:
Before scrolling:
Scrolling a little down and to the right:
Second edit: I have a Retina display. Could this be related? Is there special setup for Retina with Qt?
You should be getting an error when you try to add a widget to the scene which already has a parent:
QGraphicsProxyWidget::setWidget: cannot embed widget which is
not a toplevel widget, and is not a child of an embedded widget
QGraphicsScene::addWidget() is a wrapper around QGraphicsProxyWidget::setWidget which documentation says:
widget must be a top-level widget whose parent is 0.
To have borders blended you need to set widget to be transparent:
mywidget.setAttribute(Qt::WA_TranslucentBackground, true);

How to have QGraphicsScene not centered in QGraphicsView

How can I manualy position a QGraphicsScene inside the QGraphicsView, because the default is always centered, but I want to position it by myself.
Call the centerOn function of QGraphicsView
Scrolls the contents of the viewport to ensure that the scene coordinate pos, is centered in the view.
Alternatively, if you want to specify a rect of the area in the scene to be visible, you can use fitInView.

Drawing inside a QFrame: coordinate system

I would like to draw inside a Qt QFrame, however the QFrame will have a border. As far as I understand, the paintEvent receives a QPainter which is associated to the whole frameRect, so I will have to offset my paint operations of the border. Is this correct? Is there a way of getting a QPainter already associated to the inner part of the widget, without the (variable in size) border?
you have to consider the contentsRect contentsRect()-> Returns the area inside the widget's margins.using the return value rect of contensRect() you can restrict to draw anything inside the rect.
One way to do this would be to embed a QWidget inside the QFrame, place it in a simple QVBoxLayout layout or QStackedLayout layout with no margins and paint the QWidget instead. You'll probably get better performance if you simply offset your painting, though.

Layering UI elements in Qt Designer

I have a QLabel that I'm constantly setting it's pixmap (video playback). In my application the user needs to be able to draw (boxes) above the video. How can I layer one of the QPaintDevice classes (QWidget, QPixmap, QImage, etc.) directly above and with the same size as the QLabel for painting. This element will need to have a transparent background so shapes drawn on it will appear over the video.
Add the widget you want to draw shapes on as a child widget of the video label. Add a layout first so the child widget will match the size of the parent widget. The code would be something like this:
QHBoxLayout *layout = new QHBoxLayout(videoWidget);
QLabel *overlayWidget = new QLabel();
overlayWidget->setAlignment(Qt::AlignCenter);
overlayWidget->setText("Overlaid Text");
layout->addWidget(overlayWidget);
You should see the text overlaid on the video and it should remain centered over the video widget if it is resized. For your final code, you would use some widget subclass of your own that allowed you to intercept mouse actions and draw rectangles but that's the basic idea.

How to resize a QGraphicsView after QGraphicsView::Scale

Is there non-hideous way to resize a QGraphicsView after a call of scale().
My QGraphicsView is embedded in a QScrollArea. When I zoom i want the View the get bigger.
Thx
QGraphicsView itself inherits from QAbstractScrollArea. Embedding it within another QScrollArea would be very strange, and is likely the source of your problems. By default, when you scale a QGraphicsScene larger than the QGraphicsView in which it is displayed, it will show the necessary scroll bars.

Resources