PDA

View Full Version : drawContents in QScrollArea (Qt4)



SkripT
9th January 2006, 13:24
Hi, I want to draw a pixmap in a QScrollArea because the size of the pixmap could be larger than the viewport. I want to paint de pixmap with QPainter because in the future I want to draw selection rubberbands under the pixmap. I've seen that in QScrollView in Qt3 exists the function drawContents but in Qt4 QScrollArea doesn't exist. The problem is that I want to know how to show the scrollbars of the scrollarea if the pixmap that I paint with QPainter is larger than the viewport. Thanks.

munna
9th January 2006, 14:10
Draw whatever you want on a widget and make that widget the child of the scrollarea. Everything else will be taken care by QScrollArea.

Cheers

SkripT
9th January 2006, 15:37
Hi, I've tried to draw on a widget and make this widget the child of the scrollarea but the widget but nothing is painted. The test code is:

FotoAreaEditor::FotoAreaEditor(EditorFotos *parent)
: QScrollArea(parent)
{
foto = new QWidget;

QPainter painter;
painter.begin(foto);
painter.setPen(Qt::blue);
painter.setBrush(Qt::Dense1Pattern);
painter.drawPixmap(0, 0, QPixmap("../book.png"));
painter.end();

setWidget(foto);
setBackgroundRole(QPalette::Dark);
}


I have subclassed QScrollArea because in the future is very possible that I will have to reimplement paintEvent method. Anybody could explain me why only the scrollarea is shown?

Ballistic
9th January 2006, 17:00
You shouldn't do your painting in the constructor because the next paint event the widget receives will simply overwrite what you have painted because you haven't reimplemented that function. You could try something like:


FotoAreaEditor::FotoAreaEditor(EditorFotos *parent)
: QScrollArea(parent)
{
foto = new QWidget;

setWidget(foto);
setBackgroundRole(QPalette:Dark);
}


void FotoAreaEditor::paintEvent(QPaintEvent *e)
{
QPainter painter;
painter.begin(viewport());
painter.setPen(Qt::blue);
painter.setBrush(Qt:ense1Pattern);
painter.drawPixmap(0, 0, QPixmap("../book.png"));
painter.end();
}

You could also subclass QWidget instead and put the above painting code directly in the paintEvent of that widget.

Cheers

SkripT
9th January 2006, 19:39
Hi again, this time the problem is with the scroll area. I have subclassed QWidget class. In the constructor I resize the widget to the size of the Image. After I have reimplemented paintEvent method and with QPainter I paint the Image. The problem is that I can scroll to the bottom of the image because the scoll bars are wrong. Anybody knows why?. I update the viewport of the scrollarea after setWidget but it doesn't work :(

SkripT
9th January 2006, 19:41
Sorry in the previous thread when I say: "The problem is that I can scroll ..." I really wanted to say: The problem is that I can't scroll..."

axeljaeger
9th January 2006, 21:30
What do you mean with "wrong"? Can you give us a screenshot?

newellm
9th January 2006, 21:48
You are not using QScrollArea correctly. You need to follow 1 of two paths

1. Use QScrollArea, you will want to subclass the widget that the QScrollArea is showing, and implement the paintEvent and sizeHint(), the scrollbars will be shown depending on the size of the widget.

2. Use QAbstractScrollArea, with this one, you will want to paint inside the QAbstractScrollArea's paintEvent(with a painter opened on the viewport), you will be responsible for setting the scrollbar page step, range, and value.

Matt

SkripT
10th January 2006, 13:29
Hi, I have implemented sizeHint() of the widget that the QScrollArea is showing, as the previous post coments, and it returns the size of the image. But the scroll bars are still wrong (when I move them to the bottom, the image is not in the bottom). The only way that I have been successful is making a resize of the widget in it's constructor to the size of the image, and the same resize in the paintEvent. If I don't put any of both, the scrollbars are still wrong. Anybody could explain me why or what am I doing wrong? Thanxs and sorry for my poor english.

axeljaeger
10th January 2006, 15:57
Maybe you are setting your sizeHint too late, e.g. loading of image is done after layouting the widget?

SkripT
10th January 2006, 16:06
The image in the widget is painted in the paintEvent method with qpainter. I dont' understand what you mean with: "setting your sizeHint too late". I only have implemented it, I have to call it anywhere directly??

axeljaeger
10th January 2006, 16:39
The QLayout calls the sizeHint at some point, usually directly before QWidget::show is called. The question is wether your sizeHint can give the right size at this point. It could be the wrong size because your image is loaded to late.

I don't understand atm which size hint you reimplement because there is no widget (if you draw the image on your own in paintEvent of QAbstractScrollArea).

SkripT
10th January 2006, 16:54
Sorry, I don't draw the image in paintEvent of QAbstractScrollArea, I draw it in the paintEvent of the widget.

axeljaeger
10th January 2006, 17:43
So you will likely run into the problem I noticed. Together with your second thread with the rubberband, I strongly suggest to switch over to the other solution: Use QAbstractScollArea and do all the painting and scrolling yourself although it might be not as easy as your attempt with the two widgets.

SkripT
13th January 2006, 18:21
Hi again, I have found that if I enable the option setWidgetResizable of the ScrollArea, the pixmap is always shown because the scrollarea automatically resizes the widget that contains the scrollarea to the viewport's size. This is very useful if the pixamp is smaller than the viewport because in this case I draw the pixmap centered in the widget. And, even if the window chages it's size, the pixamp is always centered. The problem is that if the pixmap is larger than the viewport and setWidgetResizable is activated, the scroll bars are not shown. The solution is to disable setWidgetResizable and resize the widget to the size of the pixmap. I would like to know where I would have to put the instructions to: when the size of the viewport is smaller than the pixmap, disable setWidgetResizable and resize the widget to the size of the pixmap, otherwise enable the option setWidgetResizable. A possible soultion that I have tried is, in the paintEvent of the widget, obtain the pointer to the scrollarea (it's parent) and with this pointer consult the size of the viewport, but the porgram crashes. I think that's because in the first time that it acess to the scroll area isn't still initialized but it's just a suposition. I think that this method, if I could find the way to make it running, could be best way. Could anyone help me please or just tell me if this is posible? Thanks.

SkripT
14th January 2006, 11:54
Hi all, finally I have solved the problem puting the code in the paintEvent of the ScrollArea. If anybody is interested in the code take look at the thread: "QRubberband painting in the scroll area widget" by myself.