lvwd 2024-02-23 19:50 采纳率: 50%
浏览 38
已结题

#Qt Transform setTransform()在鼠标拖动移动视角是一致在原地不动,无法变换视角(细微观察似乎视图有在原地抖动),无法变换视角(细微观察似乎视图有在原地抖动)

#Qt Transform setTransform()在鼠标拖动移动视角是一致在原地不动,无法变换视角(细微观察似乎视图有在原地抖动),不知道为什么


```c++
ViewControl::ViewControl(QWidget* parent)
    : QGraphicsView(parent)
{
    m_scene = new QGraphicsScene();
    view_window = this;
    this->setMouseTracking(true);
    view_window->setScene(m_scene);
    view_window->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view_window->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    view_window->viewport()->installEventFilter(this);
    view_window->setMouseTracking(true);
    view_window->setFocusPolicy(Qt::StrongFocus);
    _modifiers = Qt::ControlModifier;
    _zoom_factor_base = 1.0015;
    originalfactor = 1;
    panSelectorDown = false;
    mouseButtonDown = false;
    m_scale = 1.0;
    m_factor_st = 1.0;
    qpix_image = nullptr;
    image_item = new QGraphicsPixmapItem();
    m_scene->setSceneRect(0, 0, 32768, 32768);  // 设置场景矩形
    last_offset_X = 0.0;
    last_offset_Y = 0.0;
    m_pixmap = nullptr;
    setInteractive(false);
    QGraphicsView::setAlignment(Qt::AlignLeft | Qt::AlignTop);
}

void ViewControl::mouseMoveEvent(QMouseEvent* e)
{
    mouseLastXY = e->pos();

    if (panSelectorDown || mouseButtonDown)
    {
        this->setCursor(Qt::ClosedHandCursor);
        //Q_UNUSED(e)
        QPointF currentMapPoint = view_window->mapToScene(e->pos());
        QPointF startMapPoint = view_window->mapToScene(rubberStartPoint);

        double dx = currentMapPoint.x() - startMapPoint.x();
        double dy = currentMapPoint.y() - startMapPoint.y();
        double offset_X = last_offset_X + dx;
        double offset_Y = last_offset_Y + dy;

        view_window->setTransformationAnchor(QGraphicsView::AnchorViewCenter);
        view_window->setTransform(QTransform(1.0, 0, 0,
                                            0, 1.0, 0,
                                            offset_X, offset_Y, 1), true);

        view_window->update();

  • 写回答

20条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-23 19:51
    关注
    获得0.45元问题酬金

    引自免费微信小程序:皆我百晓生

    ViewControl类中,您正尝试实现鼠标拖动以平移视图的功能。根据您提供的代码片段,问题可能出在如何应用变换上。setTransform()方法确实可以用来改变视图的坐标系统,但在这种情况下,每次鼠标移动时直接修改视图的平移(translation)可能会导致累积误差或抖动现象。

    为了实现平移视图功能,您应该更新视图的QGraphicsView的视图中心(view center),而不是每次都重新设置整个变换矩阵。这里是一个改进的mouseMoveEvent()方法示例:

    void ViewControl::mouseMoveEvent(QMouseEvent* e)
    {
        if (panSelectorDown || mouseButtonDown)
        {
            this->setCursor(Qt::ClosedHandCursor);
    
            QPointF currentScenePoint = view_window->mapToScene(e->pos());
            QPointF startScenePoint = view_window->mapToScene(rubberStartPoint);
    
            // 计算场景中的平移偏移量
            QPointF translation = startScenePoint - currentScenePoint;
    
            // 更新视图的变换,并保持其围绕当前视图中心进行平移
            view_window->translate(translation.x(), translation.y());
    
            // 更新下一次移动计算的起始点
            rubberStartPoint = e->pos();
    
            // 触发视图更新
            view_window->update();
        }
    }
    

    在这个修复版本中,我们不再使用setTransform()方法来设置整个变换矩阵,而是使用translate()方法,它会根据当前视图变换来增量地调整视图的位置。这将确保视图在鼠标拖动过程中平滑地移动而不发生抖动。同时,请确保在按下鼠标按钮时记录下起始点(rubberStartPoint)。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 3月2日
  • 创建了问题 2月23日

悬赏问题

  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵