0

I am having a problem where I emit a signal in a mouseMove event, but that signal does not get recieved by a slot on another object until i release the mouse.

Details: I have a class called SelectableItem, which subclasses QGraphicsObject :

#pragma once
#if !defined PARTS_SELECTABLE_ITEM_H
#define PARTS_SELECTABLE_ITEM_H

#include <QGraphicsObject>

namespace Parts {
class SelectableItem : public QGraphicsObject {
    Q_OBJECT
public:
    SelectableItem();

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) = 0;
    QRectF boundingRect() const = 0;

    void SetIsSelectedCustom(bool b);
    bool IsSelectedCustom();

    void SetIsSelectable(bool b);
    bool IsSelectable();

    void SetIsHovering(bool b);
    bool IsHovering();

    void Move(QPointF offset);

signals:
    void moveItem(QGraphicsSceneMouseEvent *e);
    void deselectAllItems();
    void deselectItem(Parts::SelectableItem*);
    void selectItem(Parts::SelectableItem*);
    void stopSelectionDrag();
    void stopMovingParts();
    void deleteSelectedItems();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *e);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *e);
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e);
    void hoverEnterEvent(QGraphicsSceneHoverEvent *e);
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *e);

    bool m_is_selected;
    bool m_is_hovering;
    bool m_is_selectable;

}; // class SelectableItem
} // namespace Parts

#endif // PARTS_SELECTABLE_ITEM_H

I have two other classes that subclass the SelectableItem class. They are Part and Terminal

Part:

#pragma once
#if !defined PARTS_PART_H
#define PARTS_PART_H

#include "PartLabel.h"
#include "PartDialog.h"
#include "Terminal.h"
#include "SelectableItem.h"
#include <QGraphicsObject>
#include <QGraphicsSvgItem>
#include <QSvgRenderer>
#include <map>

namespace Parts {

class Terminal;
class Part : public SelectableItem {
    Q_OBJECT
public:

    friend class PartLabel;

    Part();
    ~Part();

    enum PartLabelLocation {
        North,
        South,
        East,
        West
    };

    // Inherited Functions
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;
    void setPos(qreal x, qreal y);

    // Part Functions
    void SetData(std::map<std::string, std::string> data);
    void SetTerminals(std::list<Terminal*> terms);
    void AddTerminalsToScene(QGraphicsScene* s);
    void SetPartGraphic(QGraphicsSvgItem *svg);
    void SetDialog(PartDialog *d);
    std::string GetName();
    void SetName(const std::string &name);
    void Move(QPointF offset);
    PartLabel* GetLabel();
    std::map<std::string, std::string>* GetData();
    std::list<Terminal*> GetTerminalList();
    QPointF GetCenterPointPos();

    void SetLabelNorth();
    void SetLabelSouth();
    void SetLabelEast();
    void SetLabelWest();
    void ResetLabelPosition();

    QGraphicsSvgItem* GetPartSvg();

signals:
    void partRotated();

private:

    // Inherited Functions
    void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e);
    void hoverEnterEvent(QGraphicsSceneHoverEvent *e);
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *e);
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *e);

    // Part Functions
    void DrawTerminal(QPainter *painter, QPointF &point);
    QRectF CalculateBoundingBox();
    void Initialize();
    void RotateCW();
    void RotateCCW();
    void OpenPropertiesDialog();
    void SinglePartContextMenu(QGraphicsSceneContextMenuEvent *e);
    void MultiplePartContextMenu(QGraphicsSceneContextMenuEvent *e);

    // Part Members
    QGraphicsSvgItem *m_part_graphic;
    std::map<std::string, std::string> m_data;
    std::list<Terminal*> m_terminals;
    QRectF m_bounding_box;
    PartLabel *m_label;
    PartDialog *m_dialog;

    bool m_is_initialized;

    int m_label_position;

}; // class Part
}; // namespace Parts

#endif // PARTS_PART_H

Terminal:

#pragma once
#if !defined PARTS_TERMINAL_H
#define PARTS_TERMINAL_H

#define TERMINAL_RADIUS 15
#define CONNECTED_TERMINAL_RADIUS 7.5

#include "Part.h"
#include "SelectableItem.h"
#include <QGraphicsObject>

namespace Parts {
class Part;
class Connection;
class Terminal : public SelectableItem {
    Q_OBJECT
public:
    enum TerminalDirection {
        North,
        East,
        South,
        West
    };

    Terminal(const std::string &name, const QPointF &rel_coords, const std::string &direction);

    // Inherited Functions
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    QRectF boundingRect() const;

    QPointF GetRelativeCoord();
    QPointF GetConnectionCoord();
    void SetPart(Part *p);
    bool HasPart();
    void Move();
    void RotateCW();
    void RotateCCW();
    void SetIsConnected(bool b);
    bool IsConnected();

    void AddConnection(Connection *c);
    void RemoveConnection(Connection *c);
    std::list<Connection*> GetConnectionList();

signals:
    void connectionBegun(Parts::Terminal *t);
    void connectionCompleted(Parts::Terminal *t);

private:
    // Inherited Functions
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *e);
    void hoverEnterEvent(QGraphicsSceneHoverEvent *e);
    void hoverLeaveEvent(QGraphicsSceneHoverEvent *e);
    //void contextMenuEvent(QGraphicsSceneContextMenuEvent *e);

    void IncrementDirection();
    void DecrementDirection();

    QPointF m_rel_coords;
    QPointF m_rotated_rel_coords;

    bool m_is_connected;

    int m_direction;
    int m_rotation_angle;

    QRectF m_bounding_rect;
    Part *m_part;
    std::string m_name;
    std::list<Connection*> m_connections;

}; // class Terminal
} // namespace Parts

#endif // PARTS_TERMINAL_H

The SelectableItem class's mouseMove function is as follows:

void SelectableItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
    if(!m_is_selectable)
        return;

    if(m_is_selected)
        emit moveItem(e);
    else {
        emit deselectAllItems();
        emit selectItem(this);
    }
}

The signal emit selectItem(this) is instantly recieved by another class SysGraphicsScene which handles item selection.

The problem I'm having is that the Part class emits this signal via its base class and the signal is recieved by the SysGraphicsScene class instantly. However, the Terminal class emits this signal via it's base class (SelectableItem, which is the same base class that Part has.) and the signal is not recieved instantly by SysGraphicsScene but only after mouseReleased.

I have no idea why two derived classes would work differently. Any ideas?

jasonlg3d
  • 484
  • 2
  • 7
  • 18

1 Answers1

0

Ugh found the problem. Some of my Terminal objects were never getting connected to signals while som where. I knew it had to be something basic. :/

jasonlg3d
  • 484
  • 2
  • 7
  • 18