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

#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 有没有人会打学生成绩管理系统呀
  • ¥15 在使用Fiddler和夜神模拟器抓包的时候一直出现443该怎么办啊QAQ搜了好几个笔记都没有解决
  • ¥15 3x7的二维数组A、B、C,A中的任意1个数组元素与B的任意1个数组元素、同时又与C的任意1个数组元素比较,把不同位置出现相同数的比较称为无意义,反之称为有意义,把有意义的比较打印输出。
  • ¥20 预测模型怎么处理原始数据(随机森林)
  • ¥20 请问discuz3.5如何实现插入ckplayer全能播放器功能呢?
  • ¥15 博途v18仿真报错怎么解决
  • ¥15 欧姆龙plc枕式包装机 ST编程
  • ¥15 为啥快手广告联盟的广告这么难出来
  • ¥15 k8s集群重启后,kubelet一直报systemctl restart kubelet.service "Failed to delete cgroup paths"
  • ¥15 微信小程序构建工具类发布到npm,install后报错