Qt+线段拖曳示例代码

Qt线段拖曳示例代码,功能见下图。

代码如下:

canvaswidget.h

cpp 复制代码
#ifndef CANVASWIDGET_H
#define CANVASWIDGET_H

#include <QWidget>
#include <QPainter>
#include <QMouseEvent>
#include <QVector>

class CanvasWidget : public QWidget
{
    Q_OBJECT
public:
    explicit CanvasWidget(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent* event)override;
    void mousePressEvent(QMouseEvent* event)override;
    void mouseMoveEvent(QMouseEvent* event)override;
    void mouseReleaseEvent(QMouseEvent* event)override;
private:
    bool isPointValid(QPoint point)const;
    QPoint constrainPoint(QPoint point)const;
signals:
private:
    QVector<QPoint> points;
    int selectedPointIndex = -1;
};

#endif // CANVASWIDGET_H

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class CanvasWidget;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    CanvasWidget* canvas;
};
#endif // MAINWINDOW_H

canvas.widget.cpp

cpp 复制代码
#include "canvaswidget.h"
#include <QLinearGradient>
#include <QDebug>

CanvasWidget::CanvasWidget(QWidget *parent)
    : QWidget{parent}
{
    points << QPoint(50,50)<<QPoint(200,200);
    setMouseTracking(true);
    setStyleSheet("background-color:#e6f7ff;");
}

void CanvasWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    QLinearGradient gradient(0, 0, width(), height());
    gradient.setColorAt(0, QColor(230, 247, 255));
    gradient.setColorAt(1, QColor(210, 235, 255));
    painter.fillRect(rect(), gradient);

    QPen linePen(QColor(75,175,240), 3, Qt::SolidLine,
                 Qt::RoundCap, Qt::RoundJoin);

    // painter.drawLines(points);
    for(int i=1, c=points.size(); i<c; i++)
    {
        painter.drawLine(points[i-1], points[i]);
    }


    QBrush pointBrush(QColor(255, 153, 153));
    painter.setBrush(pointBrush);
    for(const auto& point: points)
    {
        painter.drawEllipse(point, 7, 7);
    }

}

void CanvasWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton)
    {
        points << QPoint(event->pos());
        update();
    }
    else if(event->button() == Qt::LeftButton)
    {
        for(int i=0; i<points.size(); i++)
        {
            const auto& point = points[i];
            if((event->pos() - point).manhattanLength()<15)
            {
                selectedPointIndex = i;
                break;
            }
        }
    }

}

void CanvasWidget::mouseMoveEvent(QMouseEvent *event)
{
    if(selectedPointIndex != -1)
    {
        points[selectedPointIndex] = constrainPoint(event->pos());
        update();
    }
}

void CanvasWidget::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    selectedPointIndex = -1;
    qDebug() << "pos:" << event->pos();
}

bool CanvasWidget::isPointValid(QPoint p) const
{
    return p.x()>=0 && p.y() >=0 && p.x()<width() && p.y()<height();
}

QPoint CanvasWidget::constrainPoint(QPoint p) const
{
    int x = p.x(), y = p.y();
    x = fmin(x, width());
    x = fmax(x, 0);
    y = fmin(y, height());
    y = fmax(y, 0);
    return QPoint(x, y);
}

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "canvaswidget.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{

    setFixedSize(600, 400);
    setStyleSheet("background-color:#ffffff;");
    setWindowTitle("drag_line");
    canvas = new CanvasWidget(this);
    canvas->setGeometry(50, 50, 500, 300);
}

MainWindow::~MainWindow()
{

}

main.cpp

cpp 复制代码
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}
相关推荐
yaoxin5211236 小时前
434. Java 日期时间 API - Period 基于日期的时间段
java·开发语言·python
凡人叶枫6 小时前
Effective C++ 条款30:透彻了解 inlining 的里里外外
linux·开发语言·c++·嵌入式开发·effective c++
noipp6 小时前
推荐题目:洛谷 P10907 [蓝桥杯 2024 国 B] 蚂蚁开会
c语言·c++·算法·编程·洛谷
学逆向的7 小时前
C++纯虚函数
开发语言·c++·网络安全
程序员二叉7 小时前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc
程序员二叉7 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
凡人叶枫8 小时前
Effective C++ 条款22:将成员变量声明为 private
linux·开发语言·c++
Qt程序员8 小时前
掌握 Linux 内核调度:从原理到实现(进程篇)
java·开发语言
code bean8 小时前
【LangChain】检索器完全指南:从向量检索到生产级 RAG 架构
java·开发语言·微服务
LabVIEW开发8 小时前
LabVIEW + MATLAB 混合编程:爆炸场测试数据精准采集方案
开发语言·matlab·labview