PDA

View Full Version : grabWidget problem



gonzoboy!
17th November 2009, 18:13
Hello all,

This is supposed to grab a section of the parent widget when this widget is moved and display the grab. It isn't working.
Any insights will be greatly appreciated!!!

TIA,

gonzoboy!

void ZoomWindow::moveFrame()
{
move(mp.x(), mp.y());

QWidget w(this->parentWidget());
w.show();
// grab a 40x40 chunk of parent widget
pm = QPixmap::grabWidget(&w, 0, 0, 39, 39);
}

void ZoomWindow::paintEvent(QPaintEvent* pe)
{
QPainter painter(this);
QRect r(0, 0, 199, 199);
QPen pen(Qt::black);

// paint the pixmap from parent zoomed 5x in ZoomWindow
painter.drawPixmap(r, pm);
painter.drawRect(r);

}

spirit
17th November 2009, 18:43
try this


...
pm = QPixmap::grabWidget(parentWidget(), 0, 0, 39, 39);
...

gonzoboy!
17th November 2009, 19:10
Thanks, that actually gave me the same strange result that grabWindow returns. Any other notions?

scascio
17th November 2009, 20:36
Hi,

When does your moveFrame() method is called?

Be careful that if it is in response of a mouseMove event,
then moving your widget inside will trigger another mouseMove, since it is moved relatively to the mouse!!

Hard to get rid of this and get expected behaviour. Think well your design.

gonzoboy!
17th November 2009, 20:57
The mouse event is in the parent. This triggers the grab in the child.

scascio
17th November 2009, 21:13
I wonder if the widget your are creating in moveFrame has the time to be painted before go out the method. The event is queued, no?

That is why spirit told you to use direclty the parent instead of creating a temporary widget.

But what about moving a simple colored QPixmap?

gonzoboy!
17th November 2009, 21:48
Scascio,

It isn't queued. How would one go about doing that?

g

gonzoboy!
17th November 2009, 21:56
Here is the trigger (in main.cpp):
QObject::connect(&w, SIGNAL(mouseMoved()), &zw, SLOT(moveFrame()));

gonzoboy!
17th November 2009, 22:07
Yes, I think you've nailed the problem. When I do the grab from the child constructor for a fixed part of the parent, it grabs fine. SO, how do I "slow it down" enough to do an updated grab after a mouseMove without really slowing the app down?


pm = QPixmap::grabWidget(parentWidget(), 0, 0, 50, 50);

scascio
17th November 2009, 22:59
In tried to solve your zoom window need and I encountered several problems


A factor 5 seems a lot.
You need to set a size for the ZoomWindow to have it painted correctly
You dont need to get through SIGNAL/SLOT since mouseMoveEvent in parent widget is a virtual method.


I think your main problem is that when you grab the widget in the child window, you will grab all the parent, so with the child(the zoom) in it!! so you need to make it invisible and restore it after.

And ones I didnt solve :
the zoom is painted under the layout in background (=>maybe a window flag?),
the mouseMoveEvent is not trigger on child widget of the layout (=>use eventFilter?)

Here is the parent widget :



#ifndef MYMAINWIDGET_H
#define MYMAINWIDGET_H

#include <QtGui/QDialog>
#include "ui_MyMainWidget.h"

#include <QMouseEvent>

#include "ZoomWindow.h"

class MyMainWidget : public QDialog {

Q_OBJECT

public:

MyMainWidget(QWidget *parent = 0)
: QDialog(parent), m_zoomWindow(this) {
ui.setupUi(this);
setMouseTracking(true);
}

virtual ~MyMainWidget() {
}

protected:

void mouseMoveEvent(QMouseEvent * event){
QWidget::mouseMoveEvent(event);
m_zoomWindow.update(event->pos());
}

private:

Ui::MyMainWidgetClass ui;

ZoomWindow m_zoomWindow;
};

#endif // MYMAINWIDGET_H



And here is the Zoom Window



#ifndef ZOOMWINDOW_H
#define ZOOMWINDOW_H

#include <QtGui/QWidget>

#include <QPixmap>
#include <QPainter>

class ZoomWindow : public QWidget {

Q_OBJECT

public:

ZoomWindow(QWidget *parent = 0, int factor=2)
:QWidget(parent), m_factor(factor) {
resize(200, 200);
}

virtual ~ZoomWindow() {
}

void update(const QPoint& point) {
setVisible(false);
m_pixmap = QPixmap::grabWidget(parentWidget(), QRect(point, size()/m_factor));
setVisible(true);
move(point);
QWidget::update();
}

protected:

virtual void paintEvent(QPaintEvent * /*event*/) {
QRect r(rect());
QPainter painter(this);
painter.setPen(Qt::black);
painter.drawPixmap(r, m_pixmap);
painter.drawRect(r);
}

private:

int m_factor;
QPixmap m_pixmap;
};

#endif // ZOOMWINDOW_H

gonzoboy!
17th November 2009, 23:10
Scoscio,

Thanks so much. I will try what you have suggested. I am working on an assignment and it specified zoom factor 5. I like the update overload approach. Stay tuned...

gonzoboy!