QSlider handle and QProxyStyle - c++

By default, QSlider move his thumbtrack by a value belonging to the pageStep() prop on mouse click. To make thumbtrack jump directly at the mouse click point, we need to create a new class inherited by QSlider.
.h
#ifndef QIMPROVEDSLIDER_H
#define QIMPROVEDSLIDER_H
#include <QSlider>
class QImprovedSlider : public QSlider
{
Q_OBJECT
protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
public:
explicit QImprovedSlider(QWidget *parent = 0);
signals:
void clicked(int value) const;
};
#endif // QIMPROVEDSLIDER_H
.cpp
#include <QWidget>
#include <QMouseEvent>
#include <QStyle>
#include <QStyleOptionSlider>
#include <QProxyStyle>
#include "QImprovedSlider.h"
class QImprovedSliderStyle : public QProxyStyle
{
public:
using QProxyStyle::QProxyStyle;
int styleHint(QStyle::StyleHint hint, const QStyleOption* option = 0,
const QWidget* widget = 0, QStyleHintReturn* returnData = 0) const
{
if (hint == QStyle::SH_Slider_AbsoluteSetButtons)
return (Qt::LeftButton | Qt::MidButton | Qt::RightButton);
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
};
QImprovedSlider::QImprovedSlider(QWidget *parent) :
QSlider(parent)
{
setStyle(new QImprovedSliderStyle(this->style()));
}
void QImprovedSlider::mousePressEvent(QMouseEvent *event) {
QStyleOptionSlider opt;
initStyleOption(&opt);
QRect sr = style()->subControlRect(QStyle::CC_Slider,
&opt,
QStyle::SC_SliderHandle,
this);
qDebug() << sr.height() << sr.width();
if (!sr.contains(event->pos()) && event->button() == Qt::LeftButton) {
if (orientation() == Qt::Vertical)
setValue(minimum() + ((maximum()-minimum()) * (height()-event->y())) / height() ) ;
else
setValue(minimum() + ((maximum()-minimum()) * event->x()) / width() ) ;
}
QSlider::mousePressEvent(event);
}
void QImprovedSlider::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
emit clicked(value());
QSlider::mouseReleaseEvent(event);
}
}
QImprovedSliderStyle make the handle drag more fluid, but in this way, the event is fired even when the click falls inside the handle, while the condition
!sr.contains(event->pos())
should avoid this.

Related

QGraphicsSceneHoverEvent not called while mouse is pressed

I have a scene that extends QGraphicsScene and has an event filter to handle all my scene logic and subsequent hover events etc happen correctly unless the mouse button is held down.
For example I have child elements in groups that have hoverEnterEvent and hoverLeaveEvent that get called correctly unless I'm holding the mouse. I've tried adjusting the code according to some answers and the documentation but I think I may be overlooking something really simple like a scene setting
The element header:
#ifndef IOELEMENT_H
#define IOELEMENT_H
#include <QGraphicsEllipseItem>
#include <QGraphicsItemGroup>
#include <QPen>
class IOElement : public QGraphicsEllipseItem {
public:
IOElement(QGraphicsItemGroup *parent=nullptr);
...
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) override;
...
};
#endif // IOELEMENT_H
The element cpp:
#include "ioelement.h"
#include <QBrush>
#include <QDebug>
#include "../nodescene.h"
#include "../nodestyles.h"
IOElement::IOElement(QGraphicsItemGroup *parent) : QGraphicsEllipseItem(parent) {
...
setAcceptHoverEvents(true);
setFlags(QGraphicsItem::GraphicsItemFlag::ItemIsSelectable |
QGraphicsItem::GraphicsItemFlag::ItemSendsScenePositionChanges |
QGraphicsItem::ItemSendsGeometryChanges);
}
void IOElement::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
NodeScene *nodeScene = dynamic_cast<NodeScene *>(scene());
nodeScene->setChildHover(this);
QPen pen;
pen.setColor(NodeStyles::Color::Pen_Hover_Normie);
pen.setWidth(2);
setPen(pen);
update();
QGraphicsEllipseItem::hoverEnterEvent(event);
}
void IOElement::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
NodeScene *nodeScene = dynamic_cast<NodeScene *>(scene());
nodeScene->setChildHover(nullptr);
QPen pen;
pen.setColor(NodeStyles::Color::IO_Pen_Normie);
pen.setWidth(1);
setPen(pen);
update();
QGraphicsEllipseItem::hoverLeaveEvent(event);
}
These hover routines work as expected and I can handle the rest of the mouse logic in the scene with a filter like so
The scene header:
#ifndef NODESCENE_H
#define NODESCENE_H
#include <QGraphicsScene>
class NodeScene : public QGraphicsScene {
Q_OBJECT
public:
using QGraphicsScene::QGraphicsScene;
explicit NodeScene(QObject *parent = nullptr);
...
IOElement * getChildHover() const;
void setChildHover(IOElement * hover=nullptr);
protected:
bool eventFilter(QObject *watched, QEvent *event);
private:
...
IOElement *hoverIO;
...
};
#endif // NODESCENE_H
The scene cpp:
#include "nodescene.h"
...
#include <QGraphicsSceneMouseEvent>
#include <QKeyEvent>
#include <QDebug>
NodeScene::NodeScene(QObject *parent) : QGraphicsScene(parent) {
...
// Events
installEventFilter(this);
}
IOElement * NodeScene::getChildHover() const { return hoverIO; }
void NodeScene::setChildHover(IOElement * hover) {
hoverIO = hover;
}
bool NodeScene::eventFilter(QObject *watched, QEvent *event) {
if(watched == this) {
QGraphicsSceneMouseEvent *mouseSceneEvent;
if(event->type() == QEvent::GraphicsSceneMousePress) { // Mouse Down
if(hoverIO) {
if(hoverIO->IsOutput()) {
activeConnection = new Connection(this, hoverIO->scenePos().x()+6, hoverIO->scenePos().y()+6);
} else {
// Check if connected first
qDebug() << "Grabbing intput";
}
}
}
else if (event->type() == QEvent::GraphicsSceneMouseRelease) { // Mouse Up
delete activeConnection;
activeConnection = nullptr;
}
else if (event->type() == QEvent::GraphicsSceneMouseMove) { // Mouse Move
mouseSceneEvent = static_cast<QGraphicsSceneMouseEvent *>(event);
int x = mouseSceneEvent->lastScenePos().rx();
int y = mouseSceneEvent->lastScenePos().ry();
if(activeConnection) {
activeConnection->DrawTo(x, y);
}
}
QKeyEvent *keyEvent;
if(event->type() == QEvent::KeyPress) { // Key Press
keyEvent = static_cast<QKeyEvent *>(event);
qDebug() << keyEvent->key();
}
}
return QGraphicsScene::eventFilter(watched, event);
}
When the mouse buttons are pressed nothing at all triggers in the hover events

How to make all objects move as cursor

I have QGroupBox with sliderclasses (child class from QLabel)
Picture:
I want to add MouseEvent: when I drag one sliderclasses - another classes will move.
Movement will be as mouse trajectory.
Like this:
Picture:
sliderclass.hpp:
#ifndef SLIDERCLASS_HPP
#define SLIDERCLASS_HPP
#include <QObject>
#include <QLabel>
#include <QMouseEvent>
class sliderclass : public QLabel
{
Q_OBJECT
public:
explicit sliderclass(QWidget *parent = 0);
void mouseMoveEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
void mouseReleaseEvent(QMouseEvent *ev);
private:
QPoint m_dragPosition;
bool firstCIsNotNull = true;
};
#endif // SLIDERCLASS_HPP
sliderclass.cpp:
#include "sliderclass.hpp"
sliderclass::sliderclass(QWidget *parent) :
QLabel(parent)
{
}
void sliderclass::mouseMoveEvent(QMouseEvent *ev)
{
if ((ev->buttons() & Qt::LeftButton) && firstCIsNotNull){
auto tmp = this->parent()->children();
for(auto obj : tmp) {
auto cbox = static_cast<QLabel*>(obj);
cbox->move(cbox->mapToParent(ev->pos() - m_dragPosition - cbox->geometry().topLeft()));
}
}
}
void sliderclass::mousePressEvent(QMouseEvent *ev)
{
if (ev->button() == Qt::LeftButton) {
m_dragPosition = ev->pos();
firstCIsNotNull = true;
}
}
void sliderclass::mouseReleaseEvent(QMouseEvent *ev)
{
if (ev->button() == Qt::LeftButton) {
firstCIsNotNull = false;
}
}
BUT! This code doesn't work for all QLabels.
All QLabels moves not by trajectory - they all move to final pos of the first QLabel and
all QLabels are layered on top of each other.

Draggable pixmaps inside a QGraphicsScene of graphic items

I have a scene with a 12*4 grid with blocks of QGraphicsItems ,when i right click on the blocks I have a contexmenu that
can add icons inside the blocks my proplem is that
I can't fingure out how can I make those icons draggable to the other blocks inside the graphic scene ,I know there is the "Draggable Icons Example" but how can I implement that code to a graphic scene.
this is the mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsPathItem>
class QGraphicsSceneMouseEvent;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
bool eventFilter(QObject *, QEvent *);
~MainWindow();
private slots:
void showContextMenu(const QPoint&);
void addPixBlock();
private:
Ui::MainWindow *ui;
QGraphicsScene *scene;
QGraphicsItem *itemAt(const QPointF&);
int x;
int y;
QMenu *Menu;
QMenu *Submenu;
QAction *Picture;
QGraphicsPixmapItem* pix;
};
#endif // MAINWINDOW_H
the mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "block.h"
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
#include <QPainter>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scene = new QGraphicsScene(this) ;
for(int row=-4;row<8;++row)
for(int column=0;column<4;++column)
{
Block *b = new Block;
scene->addItem(b);
b->setPos(row* 95,column*85);
}
ui->graphicsView->setScene(scene);
scene->installEventFilter(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
QGraphicsItem* MainWindow::itemAt(const QPointF &pos)
{
QList<QGraphicsItem*> items = scene->items(QRectF(pos - QPointF(1,1),
QSize(3,3)));
foreach(QGraphicsItem *item, items)
if (item->type() > QGraphicsItem::UserType)
return item;
return 0;
}
bool MainWindow::eventFilter(QObject *o, QEvent *e)
{
QGraphicsSceneMouseEvent *me = (QGraphicsSceneMouseEvent*) e;
switch ((int) e->type()){
case QEvent::GraphicsSceneMousePress:{
switch ((int) me->button()){
case Qt::RightButton:{
QGraphicsItem *item = itemAt(me->scenePos());
if (item && item->type() == Block::Type){
x=item->scenePos().x();
y=item->scenePos().y();
showContextMenu(item->scenePos().toPoint());
}
break;
}
}
break;
}
}
return QObject::eventFilter(o, e);
}
void MainWindow::showContextMenu(const QPoint &pos)
{
Menu= new QMenu("Menu");
Submenu=Menu->addMenu(QIcon(":/img/pix.png"),"Pix");
Picture =Submenu->addAction(QIcon(":/img/pix.png"),"Pix");
connect(Picture, SIGNAL(triggered()), this, SLOT(addPixBlock()));
Menu->exec(QCursor::pos());
}
void MainWindow::addPixBlock()
{
QPixmap pixmap(":/img/pix.png");
pix = scene->addPixmap(pixmap.scaled(70,50));
pix->setPos(x,y);
}
the block.h
#ifndef BLOCK_H
#define BLOCK_H
#include <QGraphicsPathItem>
class QGraphicsSceneMouseEvent;
class Block : public QGraphicsPathItem
{
public:
enum { Type = QGraphicsItem::UserType + 3 };
int type() const { return Type; }
Block(QGraphicsItem *parent = 0);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget
*widget);
bool eventFilter(QObject *, QEvent *);
};
#endif // BLOCK_H
the Block.cpp
#include "block.h"
#include <QPainter>
#include <QtWidgets>
class QGraphicsSceneMouseEvent;
Block::Block(QGraphicsItem *parent)
: QGraphicsPathItem(parent)
{
QPainterPath p;
//<->,|,<->,|,roundness
p.addRoundedRect(0,0,80,50, 5, 5);
setPath(p);
setAcceptDrops(true);
setAcceptedMouseButtons(Qt::LeftButton);
}
void Block::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
Q_UNUSED(option)
Q_UNUSED(widget)
painter->setPen(QPen(QColor(67, 141, 220)));
painter->setBrush(QColor(67, 141, 220,100));
painter->drawPath(path());
}
First of all if you want to place a QGraphicsPixmapItem on top of another item, a better option is to set it as your parentItem.
On the other hand we can use an event filter but a better option in this case is to implement a custom QGraphicsScene, and when pressing with the left key it allows to drag the item, for that we use QDrag and we pass the data of the item, then we overwrite the event dropEvent where we will obtain the item and establish a new parent.
graphicsscene.h
#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
class QMenu;
class QAction;
class GraphicsScene : public QGraphicsScene
{
public:
using QGraphicsScene::QGraphicsScene;
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void dropEvent(QGraphicsSceneDragDropEvent *event) override;
private:
QGraphicsPixmapItem *findPixmapItem(QGraphicsItem *item);
void createDrag(const QPointF &pos, QWidget *widget, QGraphicsItem *item);
void showContextMenu(const QPointF &pos);
void addPixBlock(QGraphicsItem *item);
QMenu *menu;
QMenu *submenu;
QAction *picture;
QGraphicsPixmapItem *pix;
};
#endif // GRAPHICSSCENE_H
graphicsscene.cpp
#include "graphicsscene.h"
#include <QDrag>
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QMenu>
#include <QMimeData>
#include <QWidget>
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
auto its = items(QRectF(event->scenePos() - QPointF(1,1), QSize(3,3)));
auto val = std::find_if(its.constBegin(), its.constEnd(), [](auto const& it){
return it->type() > QGraphicsItem::UserType;
});
if(val == its.constEnd())
return;
if(event->button() == Qt::RightButton){
showContextMenu(event->scenePos());
}
else{
createDrag(event->scenePos(), event->widget(), *val);
}
}
void GraphicsScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
QByteArray byteArray = event->mimeData()->data("Item");
QGraphicsPixmapItem * item = *reinterpret_cast<QGraphicsPixmapItem**>(byteArray.data());
QGraphicsItem *item_parent = itemAt(event->scenePos(), QTransform());
item->setParentItem(item_parent);
}
QGraphicsPixmapItem *GraphicsScene::findPixmapItem(QGraphicsItem *item){
auto chs = item->childItems();
auto val = std::find_if(chs.constBegin(), chs.constEnd(), [](auto const& it){
return static_cast<QGraphicsPixmapItem *>(it) != Q_NULLPTR;
});
return val == chs.constEnd() ? Q_NULLPTR : static_cast<QGraphicsPixmapItem *>(*val);
}
void GraphicsScene::createDrag(const QPointF &pos, QWidget *widget, QGraphicsItem *item){
QGraphicsPixmapItem *pix = findPixmapItem(item);
if(pix == Q_NULLPTR)
return;
QByteArray byteArray(reinterpret_cast<char*>(&pix),sizeof(QGraphicsPixmapItem*));
QDrag *drag = new QDrag(widget);
QMimeData * mimeData = new QMimeData;
mimeData->setData("Item",byteArray);
drag->setMimeData(mimeData);
drag->setHotSpot(pos.toPoint()-pix->scenePos().toPoint());
drag->setPixmap(pix->pixmap());
drag->start();
}
void GraphicsScene::showContextMenu(const QPointF &pos)
{
QGraphicsItem *item = itemAt(pos, QTransform());
menu= new QMenu("Menu");
submenu = menu->addMenu(QIcon(":/img/pix.png"),"Pix");
picture = submenu->addAction(QIcon(":/img/pix.png"),"Pix");
connect(picture, &QAction::triggered, [item, this](){
addPixBlock(item);
});
menu->exec(QCursor::pos());
}
void GraphicsScene::addPixBlock(QGraphicsItem *item)
{
if(findPixmapItem(item))
return;
QPixmap pixmap(":/img/pix.png");
pix = addPixmap(pixmap.scaled(70,50));
if(pix->parentItem() != item)
pix->setParentItem(item);
}
Then we establish that new scene and add the Blocks.
The complete example can be found in the following link

Designing a Qt Creator's SideBar in C++

I have created a class for making a sidebar just like in Qt Creator (one to the left). I am having no idea now to make it look exactly like the one in Qt creator as mine looks ugly!
The sidebar.h:
#ifndef _SIDEBAR_H_
#define _SIDEBAR_H_
#include <QVector>
#include <QString>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QPixmap>
#include <iostream>
class SideBar : public QWidget
{
public:
SideBar(QWidget *parent=nullptr);
void addIcon(const char *name);
void addIcon(QString &name);
private:
QVBoxLayout *_layout;
};
#endif // SIDEBAR_H
The sidebar.cpp
#include "sidebar.h"
#include <QPushButton>
#include <QIcon>
SideBar::SideBar(QWidget *parent) : QWidget(parent)
{
_layout = new QVBoxLayout(this);
setLayout(_layout);
}
void SideBar::addIcon(const char *name)
{
QString str(name);
addIcon(str);
}
void SideBar::addIcon(QString &file)
{
QPushButton *button = new QPushButton(this);
QPixmap pixmap(file);
QIcon buttonIcon(pixmap);
button->setIcon(buttonIcon);
// button->setIconSize(pixmap.rect().size());
_layout->addWidget(button);
}
This is one i want:
And this is one i got:
A possible solution is to use QAction to handle the clicks and icons, overwriting the methods paintEvent, mousePressEvent, mouseMoveEvent, leaveEvent, changing the colors regarding the state in which the widget is.
sidebar.h
#ifndef SIDEBAR_H
#define SIDEBAR_H
#include <QAction>
#include <QWidget>
class SideBar : public QWidget
{
Q_OBJECT
public:
explicit SideBar(QWidget *parent = nullptr);
void addAction(QAction *action);
QAction *addAction(const QString &text, const QIcon &icon = QIcon());
QSize minimumSizeHint() const;
signals:
public slots:
protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void leaveEvent(QEvent * event);
QAction *actionAt(const QPoint &at);
private:
QList<QAction *> mActions;
QAction *mCheckedAction;
QAction *mOverAction;
};
#endif // SIDEBAR_H
sidebar.cpp
#include "sidebar.h"
#include <QPaintEvent>
#include <QPainter>
#include <QDebug>
#include <QEvent>
#define action_height 90
SideBar::SideBar(QWidget *parent) :
QWidget(parent), mCheckedAction(NULL), mOverAction(NULL)
{
setMouseTracking(true);
}
void SideBar::paintEvent(QPaintEvent *event)
{
QPainter p(this);
QFont fontText(p.font());
fontText.setFamily("Helvetica Neue");
p.setFont(fontText);
int action_y = 0;
p.fillRect(rect(), QColor(100, 100, 100));
for(auto action: mActions)
{
QRect actionRect(0, action_y, event->rect().width(), action_height);
if(action->isChecked())
{
p.fillRect(actionRect, QColor(35, 35, 35));
}
if(action == mOverAction){
p.fillRect(actionRect, QColor(150, 150, 150));
}
p.setPen(QColor(255, 255, 255));
QSize size = p.fontMetrics().size(Qt::TextSingleLine, action->text());
QRect actionTextRect(QPoint(actionRect.width()/2 - size.width()/2, actionRect.bottom()-size.height()-5), size);
p.drawText(actionTextRect, Qt::AlignCenter, action->text());
QRect actionIconRect(0, action_y + 10, actionRect.width(), actionRect.height()-2*actionTextRect.height()-10);
QIcon actionIcon(action->icon());
actionIcon.paint(&p, actionIconRect);
action_y += actionRect.height();
}
}
QSize SideBar::minimumSizeHint() const
{
return action_height*QSize(1, mActions.size());
}
void SideBar::addAction(QAction *action)
{
mActions.push_back(action);
action->setCheckable(true);
update();
}
QAction *SideBar::addAction(const QString &text, const QIcon &icon)
{
QAction *action = new QAction(icon, text, this);
action->setCheckable(true);
mActions.push_back(action);
update();
return action;
}
void SideBar::mousePressEvent(QMouseEvent *event)
{
QAction* tempAction = actionAt(event->pos());
if(tempAction == NULL || tempAction->isChecked())
return;
qDebug()<<"clicked";
if(mCheckedAction)
mCheckedAction->setChecked(false);
if(mOverAction == tempAction)
mOverAction = NULL;
mCheckedAction = tempAction;
tempAction->setChecked(true);
update();
QWidget::mousePressEvent(event);
}
void SideBar::mouseMoveEvent(QMouseEvent *event)
{
QAction* tempAction = actionAt(event->pos());
if(tempAction == NULL){
mOverAction = NULL;
update();
return;
}
if(tempAction->isChecked() || mOverAction == tempAction)
return;
mOverAction = tempAction;
update();
QWidget::mouseMoveEvent(event);
}
void SideBar::leaveEvent(QEvent * event)
{
mOverAction = NULL;
update();
QWidget::leaveEvent(event);
}
QAction* SideBar::actionAt(const QPoint &at)
{
int action_y = 0;
for(auto action: mActions)
{
QRect actionRect(0, action_y, rect().width(), action_height);
if(actionRect.contains(at))
return action;
action_y += actionRect.height();
}
return NULL;
}
#undef action_height
The sample code is here.
Screenshots:

Qt Display tooltip after mouse hover on QGraphicsPixmapItem

I'm using QGraphicView to show game map that consist QGraphicsPixmapItems. I need to show tooltip on mouse hover at QGraphicsPixmapItem.
For saving QGraphicsPixmapItem position I using MazeItem:
#ifndef MAZEITEM_H
#define MAZEITEM_H
#include <QPoint>
#include <QGraphicsItem>
class MazeItem
{
private:
QPoint myPosition;
QString myToolTip;
public:
MazeItem();
QPoint position() const;
QString toolTip() const;
void setToolTip(const QString &toolTip);
void setPosition(const QPoint &position);
QPoint getPosition();
QGraphicsPixmapItem * pixmap;
};
#endif // MAZEITEM_H
I have widget class to display game map:
#include <QWidget>
#include <QtGui>
#include <QGraphicsView>
#include <QToolTip>
#include "mazeitem.h"
class MazeGUI : public QWidget
{
Q_OBJECT
private:
QGraphicsView * graphicsView;
QGraphicsScene * graphicsScene;
QString sceneString;
int imageSize;
QList<MazeItem> mazeItems;
void addItem(int x, int y, QPixmap picture);
bool event(QEvent *event);
int itemAt(const QPoint &pos);
public:
explicit MazeGUI(QWidget *parent = 0);
void setScene(QString sceneString);
signals:
public slots:
void redraw();
};
#endif // MAZEGUI_H
In constructor I set mouse tracking.
MazeGUI::MazeGUI(QWidget *parent) :
QWidget(parent)
{
setMouseTracking(true);
...
}
This is how I add new maze item.
void MazeGUI::addItem(int x, int y, QPixmap picture)
{
MazeItem mazeItem;
mazeItem.setPosition(QPoint(x, y));
mazeItem.setToolTip("text");
mazeItem.pixmap = this->graphicsScene->addPixmap(picture);
mazeItem.pixmap->setPos(y, x);
mazeItems.append(mazeItem);
}
And this I have from Qt tutorials,
bool MazeGUI::event(QEvent *event)
{
if (event->type() == QEvent::ToolTip) {
// HERE - it never goes here!!
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
int index = itemAt(helpEvent->pos());
if (index != -1) {
QToolTip::showText(helpEvent->globalPos(), mazeItems[index].toolTip());
} else {
QToolTip::hideText();
event->ignore();
}
return true;
}
return QWidget::event(event);
}
int MazeGUI::itemAt(const QPoint &pos)
{
for (int i=0; i < mazeItems.size(); ++i)
{
if (mazeItems[i].getPosition() == pos)
return i;
}
return -1;
}
Was adding the tooltip on wrong object:
Instead of:
mazeItem.setToolTip("text");
It should be:
mazeItem.pixmap->setToolTip("text");