Qt - QGraphicsView without ScrollBar - c++

I am trying to show a picture in it's full view using QGraphicsScene. But when ever I put the QgraphicsScene inside the QGraphicsView, I am getting a scroll bar. I tried so many ways But all are went to veins. So can anybody tell me how to obtain the full view without the scrollbar.

You might be getting scrollbars because the scene is larger than the usable area within the graphics view. By default, a QGraphicsView comes with a 1-pixel margin. To fix this, you can try:
QRect rcontent = graphicsView.contentsRect();
graphicsView.setSceneRect(0, 0, rcontent.width(), rcontent.height());
I had been getting scrollbars because I was manually setting the scene rect to the size of the graphics item I was adding -- which was as large as the QGraphicsView widget. I wasn't taking into account the margin.

QGraphicsView v;
v.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
v.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
To adjust the scrolling programmatically once these have been hidden, use one of the overloads of v.ensureVisible().

Related

Get size of QScrollArea viewport before showing

I have a custom QDialog comprised of a QStackedWidget with QScrollArea widgets for each page of the stacked widget.
I want to set the size hint for the QDialog such that the dialog is just large enough that the scroll bars for the scroll area are not visible when the dialog is first shown (i.e. ensure size of QScrollArea viewport = size hint of child widget in scroll area). Currently, the default sizeHint() implementation for the QDialog has insufficient height, which causes the vertical scroll bar to be shown when first loaded.
I thought this could be achieved by re-implementing sizeHint() for the QDialog, whereby the size hint of the dialog would be adjusted by the amount required for the size of QScrollArea viewport to equal the size hint for child widget in the scroll area (for the first page of the stacked layout). Unfortunately, in sizeHint(), the size of the QScrollArea viewport is set to the default size of QStackedWidget (640x480), and only updates to the correct size once the QDialog is shown.
Is there some way to get the correct size of the QScrollArea viewport before it is shown, or another way to achieve the desired effect of adjusting the size hint of the dialog to prevent scroll bars from being shown when it is first displayed (aside from hard-coding the dialog size).
With the composition of your dialog as:
I have a custom QDialog comprised of a QStackedWidget with QScrollArea
widgets for each page of the stacked widget.
The tricky part is to answer:
Is there some way to get the correct size of the QScrollArea viewport
before it is shown?
Well, before switching to certain page you can estimate the scroll area viewport if it is either correctly set or you can just measure the content going inside the scrollarea. I usually force the widget to demand certain height from the scroll area like that:
wdgetInScrollArea->setMinimumSize( widgetInScrollArea->sizeHint() );
wdgetInScrollArea->adjustSize(); // sometimes it is needed
The the scroll area viewport hint is then more 'adequate':
qDebug() << scrollArea->viewPortSizeHint(); // report
I don't see the code but usually it is not even required to do any custom event handling here, just prepare all the nested widgets like that.

Disable horizontal scrolling in QScrollArea completely, not just the bars

In Qt, I have a QScrollArea that has some content in it that can scroll vertically but should never, ever be allowed to scroll horizontally. Even if I disable the H scrollbars from showing, a mouse that has a scroll wheel (or touch pad) that supports horizontal motion will make it move a little bit side to side.
Now, this may partly be a layout issue... but nothing is actually off the screen.
It's probably a cop-out, but is there a way to just "lock" the scroll area from behind able to move horizontally at all?
scrollArea->verticalScrollBar()->setEnabled(false);
scrollArea->horizontalScrollBar()->setEnabled(false);
For your QScrollArea you need filter QEvent::Wheel in eventFilter method or overload wheelEvent(QWheelEvent* event) method.
Other way is create widget inherited from QWidget with overloaded eventFilter only and apply its filter to your scroll area:
scrollArea->viewport()->installEventFilter(someFilterWidget);
Did you try to set the scroll bar policy ?
myScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
http://qt-project.org/doc/qt-4.8/qabstractscrollarea.html#horizontalScrollBarPolicy-prop

Avoid automatic transition of QGraphicsScene on QGraphicsView

Qt's QGraphicsView has a habit of automatic transition/sliding of the view in such a way that everything drawn on the attached QGraphicsScene is visible. For example, suppose you've drawn something on the scene and viewing in the view. Now upon a button press you draw something along the right edge of the view. The scene/view will slide to the right slightly so that everything is again visible.
I want to prevent this to happen. How can I do that?
Thanks.
The scene rectangle of QGraphicsScene is by default the bounding rectangle of all the items in the scene. As such it grows when items are added.
The scene rectangle of QGraphicsView is by default taken from QGraphicsScene::sceneRect. If you don't want this to change automatically you can set one explicitly with QGraphicsView::setSceneRect.

Qt: Dragging a widget to scroll the widget's parent QScrollArea?

I've got a long horizontal QLabel displaying a png (the image shows a signal/time graph). Under that, I've got a QTableWidget. Both of these are in a QScrollArea because I want them to stay vertically aligned (the cells in the table correspond with the signal seen directly above them). I'm trying to add a handler to the QLabel such that the user can use the picture itself to scroll the scrollarea, rather than having to use the scrollbar. Is there a tried-and-tested way to do this? Directly setting the scrollarea's sliderPosition inside the QLabel's dragMoveEvent doesn't seem smart, because when the scrollarea scrolls it also leads to another dragMoveEvent on the (moving) QLabel.
I would suggest wrapping the combination (including the scroll area) in their own widget, and overriding the dragMoveEvent() on that widget. The dragMoveEvent() shouldn't be triggered when you change the scroll position if you are doing it this way, I wouldn't think, although I haven't actually tested it.

Setting QMainWindow at the center of screen

My QMainWindow contains a QGraphicsView, which should've minimum width and height. So, I've used the following code in the QMainWindow constructor:
ui.graphicsView->setMinimumHeight(VIEWWIDTH);
ui.graphicsView->setMinimumWidth(VIEWWIDTH);
Then I used following code to set QMainWindow at the center of the screen:
QRect available_geom = QDesktopWidget().availableGeometry();
QRect current_geom = frameGeometry();
setGeometry(available_geom.width() / 2 - current_geom.width() / 2,
available_geom.height() / 2 - current_geom.height() / 2,
current_geom.width(),
current_geom.height());
But it is not set at the center of the screen. If I omit setMinimumHeight() and setMinimumWidth() from QGraphicsView, then the main window is set at the center of the screen. How to overcome this problem? I'm using Qt 4.5.2.
Thanks.
The problem you are encountering is that Qt will delay many calculations as long as it can. When you set the minimum width and height of your graphics view, it sets a flag somewhere that the window the graphics view is in needs re-layed out. However, it won't do that until it has to... a few milliseconds before it is actually shown on screen. So, when you call rect() on your main window, you are getting the old rectangle, and not the new one.
My best recommendation is to extend the size change event in your main window, and adjust the positioning in that event. You may also have to flag when the window has actually been shown, so that you don't reposition the window if the user resizes it after it has been shown.
Alternately, you could try repositioning the window by extending the show event function and doing it there. It would probably happen before the user actually sees the window, but might flicker on occasion.