基于Qt框架實現繪圖軟件的功能
一、項目架構設計
1. 模塊劃分
// 核心類關系圖
+-------------------+ +-------------------+ +-------------------+
| MainWindow | →→→→→ | GraphicsScene | →→→→→ | CustomGraphicsItem |
| - 工具欄/菜單 | | - 圖形管理 | | - 圖形基類 |
| - 狀態欄 | | - 坐標轉換 | | - 屬性存儲 |
+-------------------+ +-------------------+ +-------------------+
2. 關鍵類設計
// 自定義圖形基類
class CustomGraphicsItem : public QGraphicsItem {
public:
enum ItemType { RECT, ELLIPSE, LINE, TEXT };
CustomGraphicsItem(ItemType type, QGraphicsItem *parent = nullptr);
QRectF boundingRect() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
// 屬性設置接口
void setColor(const QColor &color);
void setRotationAngle(qreal angle);
void setScaleFactor(qreal factor);
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private:
ItemType m_type;
QColor m_color;
qreal m_rotation;
qreal m_scale;
QPointF m_startPos;
};
二、核心功能實現
1. 圖形繪制模塊
// 自定義矩形繪制
CustomGraphicsRectItem::CustomGraphicsRectItem(QGraphicsItem *parent)
: QGraphicsRectItem(-50, -50, 100, 50, parent), m_type(RECT) {
setFlag(ItemIsMovable | ItemIsSelectable);
setAcceptHoverEvents(true);
}
// 繪制事件處理
void CustomGraphicsRectItem::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget *widget) {
painter->setPen(Qt::black);
painter->setBrush(QBrush(m_color));
painter->drawRect(rect());
// 繪制控制點(縮放手柄)
QPainterPath handles;
handles.addEllipse(rect().adjusted(0,0,-5,-5).topLeft(), 5,5);
handles.addEllipse(rect().adjusted(0,0,-5,-5).topRight(), 5,5);
painter->drawPath(handles);
}
2. 縮放與旋轉實現
// 視圖縮放(支持鼠標滾輪)
void GraphicsView::wheelEvent(QWheelEvent *event) {
if(event->angleDelta().y() > 0) {
scale(1.1, 1.1); // 放大
} else {
scale(0.9, 0.9); // 縮小
}
}
// 圖形旋轉(按住Ctrl+拖動)
void CustomGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
if(event->modifiers() == Qt::ControlModifier) {
m_startPos = event->scenePos();
} else {
QGraphicsItem::mousePressEvent(event);
}
}
void CustomGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
if(event->modifiers() == Qt::ControlModifier) {
qreal delta = (event->scenePos() - m_startPos).manhattanLength();
setRotation(rotation() + delta / 2); // 每像素旋轉0.5度
m_startPos = event->scenePos();
} else {
QGraphicsItem::mouseMoveEvent(event);
}
}
三、交互功能實現
1. 圖形選擇與操作
// 多選處理
void MainWindow::keyPressEvent(QKeyEvent *event) {
if(event->key() == Qt::Key_Control) {
view->setDragMode(QGraphicsView::RubberBandDrag);
}
}
// 組合操作
void MainWindow::onGroupAction() {
QList<QGraphicsItem *> selected = scene->selectedItems();
if(selected.size() < 2) return;
QGraphicsItemGroup *group = new QGraphicsItemGroup;
for(auto item : selected) {
group->addToGroup(item);
}
scene->addItem(group);
}
// 反選功能
void MainWindow::onInvertSelection() {
QList<QGraphicsItem *> allItems = scene->items();
for(auto item : allItems) {
item->setSelected(!item->isSelected());
}
}
四、界面設計
1. 工具欄配置
// 創建工具欄
QToolBar *toolbar = addToolBar("繪圖工具");
// 添加繪圖按鈕
QAction *rectAction = new QAction(QIcon(":/icons/rect.png"), "矩形", this);
connect(rectAction, &QAction::triggered, [=]{
scene->addItem(new CustomGraphicsRectItem);
});
// 添加縮放控件
QSpinBox *zoomSpinBox = new QSpinBox;
zoomSpinBox->setRange(10, 400);
zoomSpinBox->setValue(100);
connect(zoomSpinBox, QOverload<int>::of(&QSpinBox::valueChanged), [=](int val){
view->setTransform(QTransform::fromScale(val/100.0, val/100.0));
});
toolbar->addWidget(zoomSpinBox);
五、性能優化方案
1. 雙緩沖繪圖
// 在自定義圖形項中啟用雙緩沖
void CustomGraphicsItem::paint(QPainter *painter, ...) {
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
// ... 繪制邏輯
}
2. 批量更新
// 啟用場景批量更新
void MainWindow::batchUpdate() {
scene->blockSignals(true);
scene->prepareGeometryChange();
// 執行多個圖形操作
scene->blockSignals(false);
scene->update();
}
六、擴展功能實現
1. 文件操作
// 保存為SVG格式
void MainWindow::onSaveSvg() {
QSvgGenerator generator;
generator.setFileName("drawing.svg");
generator.setSize(QSize(800,600));
QPainter painter(&generator);
scene->render(painter);
}
// 導入圖像
void MainWindow::onImportImage() {
QString fileName = QFileDialog::getOpenFileName(this, "導入圖片", "", "Images (*.png *.jpg)");
if(!fileName.isEmpty()) {
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(QPixmap(fileName));
scene->addItem(item);
}
}
七、調試技巧
1. 坐標系調試
// 在狀態欄顯示坐標
void MainWindow::mouseMoveEvent(QMouseEvent *event) {
QPointF scenePos = view->mapToScene(event->pos());
statusBar()->showMessage(QString("Scene: (%1, %2)").arg(scenePos.x()).arg(scenePos.y()));
}
2. 性能監控
// 繪制耗時統計
QElapsedTimer timer;
timer.start();
// ... 繪制操作
qDebug() << "繪制耗時:" << timer.elapsed() << "ms";
參考代碼 qt 繪圖軟件,實現簡單圖形的繪制,縮放等功能 www.youwenfan.com/contentcnj/69827.html
八、完整工程結構
DrawingApp/
├── Src/
│ ├── main.cpp
│ ├── mainwindow.cpp
│ ├── graphicsview.cpp
│ └── customitem.cpp
├── Inc/
│ ├── mainwindow.h
│ ├── graphicsview.h
│ └── customitem.h
├── Res/
│ ├── icons/ # 圖標資源
│ └── styles/ # 樣式表
└── CMakeLists.txt
九、關鍵技術點
-
圖形變換矩陣
使用
QTransform實現復合變換:QTransform transform; transform.translate(100, 100); // 平移 transform.rotate(45); // 旋轉 transform.scale(2, 2); // 縮放 item->setTransform(transform); -
事件過濾器
實現全局快捷鍵:
qApp->installEventFilter(this); bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if(event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); if(keyEvent->key() == Qt::Key_Z) { // 撤銷操作 return true; } } return QMainWindow::eventFilter(obj, event); }
浙公網安備 33010602011771號