C++Qt不用UI界面的方式实现类似multisim中复制拖拽器件并且器件之间连接起来的功能的完整代码
时间: 2024-02-03 17:11:17 浏览: 70
在不使用UI界面的情况下实现类似Multisim中复制拖拽器件并且器件之间连接起来的功能,需要用到以下技术:
1. 继承QWidget类来实现自定义控件;
2. 用QGraphicsScene和QGraphicsView来实现绘图;
3. 用QGraphicsItem实现器件的拖拽和连接。
下面是一个简单的示例代码,实现了两个器件之间的连接和拖拽复制的功能:
```
#include <QApplication>
#include <QWidget>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsEllipseItem>
#include <QGraphicsLineItem>
#include <QKeyEvent>
#include <QDebug>
class CircuitItem : public QGraphicsItem
{
public:
CircuitItem(QGraphicsItem *parent = nullptr)
: QGraphicsItem(parent)
{
setFlag(QGraphicsItem::ItemIsMovable, true);
setFlag(QGraphicsItem::ItemIsSelectable, true);
}
QRectF boundingRect() const override
{
return QRectF(-25, -25, 50, 50);
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
painter->setBrush(Qt::red);
painter->drawEllipse(-25, -25, 50, 50);
}
void addWire(CircuitItem *other)
{
m_wires.append(other);
other->m_wires.append(this);
update();
other->update();
}
void removeWire(CircuitItem *other)
{
m_wires.removeOne(other);
other->m_wires.removeOne(this);
update();
other->update();
}
void removeAllWires()
{
for (CircuitItem *item : m_wires)
{
item->m_wires.removeOne(this);
item->update();
}
m_wires.clear();
update();
}
QVector<CircuitItem *> wires() const
{
return m_wires;
}
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override
{
if (event->button() == Qt::LeftButton)
{
m_dragStartPos = pos();
m_isDragging = true;
for (CircuitItem *item : m_wires)
{
item->removeWire(this);
}
}
else if (event->button() == Qt::RightButton)
{
removeAllWires();
scene()->removeItem(this);
delete this;
}
}
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
{
if (m_isDragging)
{
setPos(m_dragStartPos + event->pos() - event->buttonDownPos(Qt::LeftButton));
for (CircuitItem *item : m_wires)
{
item->update();
}
}
}
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override
{
if (m_isDragging)
{
m_isDragging = false;
for (QGraphicsItem *item : collidingItems())
{
CircuitItem *circuitItem = qgraphicsitem_cast<CircuitItem *>(item);
if (circuitItem && circuitItem != this)
{
addWire(circuitItem);
}
}
}
}
void paintEvent(QPaintEvent *)
{
QPainter painter(this);
paint(&painter, nullptr, nullptr);
}
private:
QPointF m_dragStartPos;
bool m_isDragging = false;
QVector<CircuitItem *> m_wires;
};
class CircuitScene : public QGraphicsScene
{
public:
CircuitScene(QObject *parent = nullptr)
: QGraphicsScene(parent)
{
}
protected:
void keyPressEvent(QKeyEvent *event) override
{
if (event->key() == Qt::Key_C)
{
CircuitItem *item = new CircuitItem;
addItem(item);
item->setPos(0, 0);
}
else if (event->key() == Qt::Key_V)
{
QList<QGraphicsItem *> items = selectedItems();
for (QGraphicsItem *item : items)
{
CircuitItem *circuitItem = qgraphicsitem_cast<CircuitItem *>(item);
if (circuitItem)
{
CircuitItem *copy = new CircuitItem;
addItem(copy);
copy->setPos(circuitItem->pos() + QPointF(50, 50));
}
}
}
else if (event->key() == Qt::Key_Delete)
{
QList<QGraphicsItem *> items = selectedItems();
for (QGraphicsItem *item : items)
{
CircuitItem *circuitItem = qgraphicsitem_cast<CircuitItem *>(item);
if (circuitItem)
{
circuitItem->removeAllWires();
removeItem(circuitItem);
delete circuitItem;
}
}
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CircuitScene scene;
QGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
view.setBackgroundBrush(Qt::white);
view.setDragMode(QGraphicsView::RubberBandDrag);
view.show();
return a.exec();
}
```
这个示例代码中,CircuitItem类继承自QGraphicsItem,实现了器件的拖拽和连接功能。CircuitScene类继承自QGraphicsScene,处理了键盘事件,实现了复制和删除器件的功能。在main函数中,创建了一个CircuitScene对象和一个QGraphicsView对象,将其显示出来。
阅读全文