mhennings
5th December 2012, 12:51
Hi,
I'm using Qt 4.7.4.
I noticed today that the area that's sensitive to mouse hover events at QGraphicsItems is too large: There is a 1px transparent area to the left and to the top of the QGraphicsItem where QGraphicsSceneHoverEvents are generated for the item.
Is that a (known) bug?
Does anybody know a workaround?
sample code:
Just include this code as header (.h), create a CHoverTest and show() it from your main.
Then hover over the two boxes shown in the window.
The two boxes are 2x4px each.
The size of the hover sensitive areas is 3x5px.
#include <QGraphicsItem>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsScene>
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QGraphicsView>
#include <QtGui/QGridLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_CHoverTest
{
public:
QWidget *centralWidget;
QGridLayout *gridLayout;
QGraphicsView *view;
void setupUi(QWidget *CHoverTest)
{
if (CHoverTest->objectName().isEmpty())
CHoverTest->setObjectName(QString::fromUtf8("CHoverTest"));
CHoverTest->resize(200, 200);
centralWidget = new QWidget(CHoverTest);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
gridLayout = new QGridLayout(centralWidget);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
gridLayout->setContentsMargins(0, 0, 0, 0);
view = new QGraphicsView(centralWidget);
view->setObjectName(QString::fromUtf8("view"));
gridLayout->addWidget(view, 0, 0, 1, 1);
retranslateUi(CHoverTest);
QMetaObject::connectSlotsByName(CHoverTest);
} // setupUi
void retranslateUi(QWidget *CHoverTest)
{
CHoverTest->setWindowTitle(QApplication::translate("CHoverTest", "MainWindow", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class CHoverTest: public Ui_CHoverTest {};
} // namespace Ui
QT_END_NAMESPACE
class CCustomGraphicsScene : public QGraphicsScene
{
// from http://tufangorel.blogspot.de/2011/08/draw-grid-on-qgraphicsscene.html
public:
CCustomGraphicsScene(const QRectF &sceneRect, QObject *parent)
: QGraphicsScene(sceneRect, parent)
{
}
protected:
static const int GRID_STEP = 1;
qreal round(qreal val, int step)
{
int tmp = int(val) + step /2;
tmp -= tmp % step;
return qreal(tmp);
}
void drawBackground(QPainter * painter, const QRectF & rect )
{
int step = GRID_STEP;
painter->setPen(QPen(QColor(200, 200, 255, 125)));
// draw horizontal grid
qreal start = round(rect.top(), step);
if (start > rect.top()) {
start -= step;
}
for (qreal y = start - step; y < rect.bottom(); ) {
y += step;
painter->drawLine(rect.left(), y, rect.right(), y);
}
// now draw vertical grid
start = round(rect.left(), step);
if (start > rect.left()) {
start -= step;
}
for (qreal x = start - step; x < rect.right(); ) {
x += step;
painter->drawLine(x, rect.top(), x, rect.bottom());
}
}
};
class CHoverItem : public QGraphicsRectItem
{
public:
CHoverItem(QGraphicsItem *parentItem, QGraphicsScene *scene)
: QGraphicsRectItem(QRectF(0, 0, 2, 4), parentItem, scene)
{
setAcceptHoverEvents(true);
setToolTip("width: 2px, height: 4px");
}
~CHoverItem()
{
}
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *evt)
{
setBrush(QBrush(Qt::green));
update();
}
void hoverLeaveEvent(QGraphicsSceneHoverEvent *evt)
{
setBrush(QBrush(Qt::blue));
update();
}
};
class CHoverTest : public QWidget
{
Q_OBJECT
public:
CHoverTest(QWidget *parent = 0)
: QWidget(parent, Qt::Window)
{
ui.setupUi(this);
setWindowTitle(QString("Qt version: %1").arg(QT_VERSION_STR));
QGraphicsScene *scene = new CCustomGraphicsScene(QRectF(0, 0, 10, 10), this);
ui.view->setScene(scene);
CHoverItem *item;
item = new CHoverItem(NULL, scene);
item->setPos(2, 4);
item = new CHoverItem(NULL, scene);
item->setPos(4, 2);
ui.view->scale(20, 20);
ui.view->setToolTip("width: 10px, height: 10px, zoom: 20x");
//scene->setSceneRect(scene->itemsBoundingRect());
//scene->update();
}
~CHoverTest()
{
}
private:
Ui::CHoverTest ui;
};
I'm using Qt 4.7.4.
I noticed today that the area that's sensitive to mouse hover events at QGraphicsItems is too large: There is a 1px transparent area to the left and to the top of the QGraphicsItem where QGraphicsSceneHoverEvents are generated for the item.
Is that a (known) bug?
Does anybody know a workaround?
sample code:
Just include this code as header (.h), create a CHoverTest and show() it from your main.
Then hover over the two boxes shown in the window.
The two boxes are 2x4px each.
The size of the hover sensitive areas is 3x5px.
#include <QGraphicsItem>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsScene>
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QGraphicsView>
#include <QtGui/QGridLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class Ui_CHoverTest
{
public:
QWidget *centralWidget;
QGridLayout *gridLayout;
QGraphicsView *view;
void setupUi(QWidget *CHoverTest)
{
if (CHoverTest->objectName().isEmpty())
CHoverTest->setObjectName(QString::fromUtf8("CHoverTest"));
CHoverTest->resize(200, 200);
centralWidget = new QWidget(CHoverTest);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
gridLayout = new QGridLayout(centralWidget);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
gridLayout->setContentsMargins(0, 0, 0, 0);
view = new QGraphicsView(centralWidget);
view->setObjectName(QString::fromUtf8("view"));
gridLayout->addWidget(view, 0, 0, 1, 1);
retranslateUi(CHoverTest);
QMetaObject::connectSlotsByName(CHoverTest);
} // setupUi
void retranslateUi(QWidget *CHoverTest)
{
CHoverTest->setWindowTitle(QApplication::translate("CHoverTest", "MainWindow", 0, QApplication::UnicodeUTF8));
} // retranslateUi
};
namespace Ui {
class CHoverTest: public Ui_CHoverTest {};
} // namespace Ui
QT_END_NAMESPACE
class CCustomGraphicsScene : public QGraphicsScene
{
// from http://tufangorel.blogspot.de/2011/08/draw-grid-on-qgraphicsscene.html
public:
CCustomGraphicsScene(const QRectF &sceneRect, QObject *parent)
: QGraphicsScene(sceneRect, parent)
{
}
protected:
static const int GRID_STEP = 1;
qreal round(qreal val, int step)
{
int tmp = int(val) + step /2;
tmp -= tmp % step;
return qreal(tmp);
}
void drawBackground(QPainter * painter, const QRectF & rect )
{
int step = GRID_STEP;
painter->setPen(QPen(QColor(200, 200, 255, 125)));
// draw horizontal grid
qreal start = round(rect.top(), step);
if (start > rect.top()) {
start -= step;
}
for (qreal y = start - step; y < rect.bottom(); ) {
y += step;
painter->drawLine(rect.left(), y, rect.right(), y);
}
// now draw vertical grid
start = round(rect.left(), step);
if (start > rect.left()) {
start -= step;
}
for (qreal x = start - step; x < rect.right(); ) {
x += step;
painter->drawLine(x, rect.top(), x, rect.bottom());
}
}
};
class CHoverItem : public QGraphicsRectItem
{
public:
CHoverItem(QGraphicsItem *parentItem, QGraphicsScene *scene)
: QGraphicsRectItem(QRectF(0, 0, 2, 4), parentItem, scene)
{
setAcceptHoverEvents(true);
setToolTip("width: 2px, height: 4px");
}
~CHoverItem()
{
}
protected:
void hoverEnterEvent(QGraphicsSceneHoverEvent *evt)
{
setBrush(QBrush(Qt::green));
update();
}
void hoverLeaveEvent(QGraphicsSceneHoverEvent *evt)
{
setBrush(QBrush(Qt::blue));
update();
}
};
class CHoverTest : public QWidget
{
Q_OBJECT
public:
CHoverTest(QWidget *parent = 0)
: QWidget(parent, Qt::Window)
{
ui.setupUi(this);
setWindowTitle(QString("Qt version: %1").arg(QT_VERSION_STR));
QGraphicsScene *scene = new CCustomGraphicsScene(QRectF(0, 0, 10, 10), this);
ui.view->setScene(scene);
CHoverItem *item;
item = new CHoverItem(NULL, scene);
item->setPos(2, 4);
item = new CHoverItem(NULL, scene);
item->setPos(4, 2);
ui.view->scale(20, 20);
ui.view->setToolTip("width: 10px, height: 10px, zoom: 20x");
//scene->setSceneRect(scene->itemsBoundingRect());
//scene->update();
}
~CHoverTest()
{
}
private:
Ui::CHoverTest ui;
};