我正在处理一个从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);
}
}
2条答案
按热度按时间zbq4xfa01#
你可以使用一个普通的事件过滤器,检查它是否是一个鼠标按下,释放或移动事件,然后将它转换为一个鼠标事件,然后做任何你想做的事情。
不要忘记在类上安装事件过滤器
tkclm6bt2#
从你的问题中我看不出你有什么特别的需要。信号
&QGraphicsScene::selectionChanged
对你来说不够吗?项目设置为交互吗?所以简单地说:声明插槽:
定义插槽:
并连接: