c++ 未调用QWidget::鼠标按下事件()

xytpbqjk  于 2023-02-20  发布在  其他
关注(0)|答案(2)|浏览(99)

我正在处理一个从QObject和QGraphicsItem派生的TreeViewNode类,负责创建树视图(显示一个家族树)的各个节点并将它们添加到场景中。我确保在类构造函数中包含setFlag(QGraphicsItem::ItemIsSelectable);方法,并重载了mousePressEvent,如下所示:

void TreeViewNode::mousePressEvent(QGraphicsSceneMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        qDebug() << "Mouse pressed on node: " << m_node->getPatient()->get_Name().c_str();
        emit clicked(this);
    }
    QGraphicsItem::mousePressEvent(event);
}

单击的信号在头文件中定义为void clicked(TreeViewNode* node);,然后在MainWindow中有一个updateSelectedPatient插槽

void MainWindow::updateSelectedPatient(TreeViewNode* node) {
    selected->setSelectedPatient(node->getNode()->getPatient());
}

以及MainWindow构造函数中对应的connect语句

connect(treeView, &TreeViewNode::clicked, this, &MainWindow::updateSelectedPatient);

执行时,我在视图中看到已添加到场景中的节点,但当我单击它们时,什么也没发生(我通过调试知道,还因为setSelectedPatient()方法更新了一个小部件,显示当前选定患者的患者信息);看起来mousePressEvent()根本没有被调用。。任何帮助都将非常感激,谢谢你的时间!
编辑:

//TreeViewNode.hpp
class TreeViewNode : public QObject, public QGraphicsItem {
    Q_OBJECT
    Q_INTERFACES(QGraphicsItem)

private:
    node* m_node;
    Family_tree* m_family;
    QGraphicsScene* m_scene;
    static std::set<node*> addedNodes;

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent* event) override;

public:
    TreeViewNode(node* node, Family_tree* family, QGraphicsScene* scene, QGraphicsItem* parent = nullptr);
    TreeViewNode* getTreeViewNode(node* n);
    node* getNode() const;
    static void clearAddedNodes();
    void updateNode(Patient& patient);
    QRectF boundingRect() const override;
    void drawBranches(QPainter* painter);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;

signals:
    void clicked(TreeViewNode* node);
};

//TreeViewNode.cpp
TreeViewNode::TreeViewNode(node* node, Family_tree* family, QGraphicsScene* scene, QGraphicsItem* parent) : QGraphicsItem(parent), m_node(node), m_family(family), m_scene(scene) {
    if (m_node == m_family->get_root()) {m_scene->addItem(this);}
    addedNodes.insert(m_node);
    setFlag(QGraphicsItem::ItemIsSelectable);
    qDebug() << "Scene item count: " << m_scene->items().count();

    if (m_node->getFather()) {
        auto father = m_node->getFather();
        if (addedNodes.count(father) > 0) {return;}
        TreeViewNode* fatherNode = new TreeViewNode(m_node->getFather(), family, m_scene, this);
        fatherNode->setPos(-50, -100);
    }

    if (m_node->getMother()) {
        auto mother = m_node->getMother();
        if (addedNodes.count(mother) > 0) {return;}
        TreeViewNode* motherNode = new TreeViewNode(m_node->getMother(), family, m_scene, this);
        motherNode->setPos(50, -100);
    }

    if (m_node->getSpouse()) {
        auto spouse = m_node->getSpouse();
        if (addedNodes.count(spouse) > 0) {return;}
        TreeViewNode* spouseNode = new TreeViewNode(m_node->getSpouse(), family, m_scene, this);
        spouseNode->setPos(100, 0);
    }

    int childCount = 0;
    for (auto child : m_node->getChildren()) {
        if (addedNodes.count(child) > 0) {return;}
        TreeViewNode* childNode = new TreeViewNode(child, family, m_scene, this);
        childCount++;
        double xPos, yPos;
        xPos = pos().x() + 50 + 100 * (childCount - (m_node->getChildren().size() + 1) / 2.0);
        yPos = pos().y() + 100;
        childNode->setPos(xPos, yPos);
    }
}
zbq4xfa0

zbq4xfa01#

你可以使用一个普通的事件过滤器,检查它是否是一个鼠标按下,释放或移动事件,然后将它转换为一个鼠标事件,然后做任何你想做的事情。

    • 示例:**
bool YourWidgetClass::eventFilter(QObject* object, QEvent* event)
{
if (object == YourInstance)
{
   switch (event->type()) 
   {
    case QEvent::GraphicsSceneMousePress: 
    {
       QMouseEvent * mouseEvent = static_cast<QMouseEvent*>(event);
       switch (mouseEvent->button())
       {
          case Qt::LeftButton:
                // Handle left button pressed here
                return true;

            case Qt::RightButton:
                // Handle right button pressed here
                return true;
            default:
                break;
        }
        break;
     }
   }
}

不要忘记在类上安装事件过滤器

YourClassCtor->installEventFilter(this)
tkclm6bt

tkclm6bt2#

从你的问题中我看不出你有什么特别的需要。信号&QGraphicsScene::selectionChanged对你来说不够吗?项目设置为交互吗?所以简单地说:
声明插槽:

public slots:
   void selectionChanged();

定义插槽:

void MainWindow::selectionChanged()
{
  qDebug() << ...... ;
}

并连接:

connect(scene,&QGraphicsScene::selectionChanged,this,&MainWindow::selectionChanged);

相关问题