Qt如何重写QScrollArea的wheelEvent()事件以实现图片随滚轮操作放大缩小?

Jaxtin 2017-12-10 10:33:16
各位大佬们.
Hello, my god.

这个问题是这样的.
This problem is about QT event.

QScrollArea在用QLable进行图片填充后,当图片尺寸过大时,QScrollArea会显示垂直、水平两个滚动条;但现在的遇到的问题是,它默认给鼠标滚轮添加了一个垂直滚动条的滚动事件,滚轮上下滚动时,滚动条也上下滚动。
于是当我重写wheelEvent事件后,只有当滚动条滚到头的时候,我写的缩放滚动条的事件才会执行,这样感觉很不科学,大家有神马解决办法吗?跪谢.....

贴上wheelEvent()的代码


private slots:
// Reimplement the wheelEvent() to Achieve Zoom in and Zoom out.
void wheelEvent(QWheelEvent *e);
void MatchWindowSingle::wheelEvent(QWheelEvent *e)
{
// If numDegress > 0, then zoom in,
// else, zoom out.
// The scale control the picture's size.
int numDegress = e->delta();

// Update ScrollArea 下面是执行图片缩放的函数代码
if (ui.sa_geoImage->hasFocus()){
identityScaleFactor(&numDegress, &scaleFactor_MIN_g, &scaleFactor_g);
updateScrollArea(&geoPic, ui.sa_geoImage, &geoImageLable, &scaleFactor_g);
}else if (ui.sa_videoImage->hasFocus()){
identityScaleFactor(&numDegress, &scaleFactor_MIN_v, &scaleFactor_v);
updateScrollArea(&videoPic, ui.sa_videoImage, &videoImageLable, &scaleFactor_v);
}
}
...全文
3884 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jaxtin 2020-08-06
  • 打赏
  • 举报
回复 1
引用一下那个连接里的帖子: 就是通过viewport()返回QScrollArea的Viewport属性,然后为这个东西添加事件过滤器而不是直接把过滤器添加到scrollArea上。
Test客服 2020-07-22
  • 打赏
  • 举报
回复
会敲code的猫 2020-05-14
  • 打赏
  • 举报
回复
可不可以和小白说一下具体怎么修改viewport()呀
Jaxtin 2019-06-17
  • 打赏
  • 举报
回复 1
时隔两年,终于在某一日想起这个帖子,结个贴以缅怀当初干劲满满的自己 首先,wheelEvent()并不是QScrollArea本身的虚函数,它是从QWiget中继承来的方法;当初重写时,既没有重写QScrollArea,也没有考虑到它通过QScrollArea::setWiget()所设置的QLabel部件,而是重写了QScrollArea的父窗体MainWindowSingle; 然后,为了解除QScrollArea对wheelEvent的控制,我们重写MainWindowSingle::wheelEvent,或是使用事件过滤器都可以,前提是要解除QScrollArea中QLabel对wheelEvent的控制,因为QScrollArea本身并没有控制到wheelEvent的纵向滚动。 综上,问题中的代码可以类似的改写如下;当然使用eventFilter也是一样的:

QLabel *pGeoImgLabel = new QLabel;
QLabel *pVideoImgLabeo = new QLabel;
ui.sa_geoImage->setWidget(pGeoImgLabel);
ui.sa_geoImage->setWidget(pVideoImgLabeo);

private slots:
    // Reimplement the wheelEvent() to Achieve Zoom in and Zoom out.      
    void wheelEvent(QWheelEvent *e);
void MatchWindowSingle::wheelEvent(QWheelEvent *e)
{
    // If numDegress > 0, then zoom in,
    // else, zoom out.
    // The scale control the picture's size.
    int numDegress = e->delta();   
 
    // Update ScrollArea 下面是执行图片缩放的函数代码
    if (pGeoImgLabel->hasFocus()){
        identityScaleFactor(&numDegress, &scaleFactor_MIN_g, &scaleFactor_g);
        updateScrollArea(&geoPic, ui.sa_geoImage, &geoImageLable, &scaleFactor_g);
        return true;
    }else if (pVideoImgLabel->hasFocus()){
        identityScaleFactor(&numDegress, &scaleFactor_MIN_v, &scaleFactor_v);
        updateScrollArea(&videoPic, ui.sa_videoImage, &videoImageLable, &scaleFactor_v);
        return true;
    }
}
Jaxtin 2019-06-17
  • 打赏
  • 举报
回复
引用 1 楼 weixin_38838242 的回复:
大佬解决了吗。。?我刚好也遇到这个问题,如果解决了可以分享下经验吗
有一日终于还是卡在这个坑上,实际上接收滚动条事件的是scrollArea->viewport();从http://www.setnode.com/blog/mouse-wheel-events-event-filters-and-qscrollarea/获得的帮助。。。。
Jaxtin 2019-06-17
  • 打赏
  • 举报
回复 1
引用 6 楼 Toyimo 的回复:
时隔两年,终于在某一日想起这个帖子,结个贴以缅怀当初干劲满满的自己 首先,wheelEvent()并不是QScrollArea本身的虚函数,它是从QWiget中继承来的方法;当初重写时,既没有重写QScrollArea,也没有考虑到它通过QScrollArea::setWiget()所设置的QLabel部件,而是重写了QScrollArea的父窗体MainWindowSingle; 然后,为了解除QScrollArea对wheelEvent的控制,我们重写MainWindowSingle::wheelEvent,或是使用事件过滤器都可以,前提是要解除QScrollArea中QLabel对wheelEvent的控制,因为QScrollArea本身并没有控制到wheelEvent的纵向滚动。 综上,问题中的代码可以类似的改写如下;当然使用eventFilter也是一样的:

QLabel *pGeoImgLabel = new QLabel;
QLabel *pVideoImgLabeo = new QLabel;
ui.sa_geoImage->setWidget(pGeoImgLabel);
ui.sa_geoImage->setWidget(pVideoImgLabeo);

private slots:
    // Reimplement the wheelEvent() to Achieve Zoom in and Zoom out.      
    void wheelEvent(QWheelEvent *e);
void MatchWindowSingle::wheelEvent(QWheelEvent *e)
{
    // If numDegress > 0, then zoom in,
    // else, zoom out.
    // The scale control the picture's size.
    int numDegress = e->delta();   
 
    // Update ScrollArea 下面是执行图片缩放的函数代码
    if (pGeoImgLabel->hasFocus()){
        identityScaleFactor(&numDegress, &scaleFactor_MIN_g, &scaleFactor_g);
        updateScrollArea(&geoPic, ui.sa_geoImage, &geoImageLable, &scaleFactor_g);
        return true;
    }else if (pVideoImgLabel->hasFocus()){
        identityScaleFactor(&numDegress, &scaleFactor_MIN_v, &scaleFactor_v);
        updateScrollArea(&videoPic, ui.sa_videoImage, &videoImageLable, &scaleFactor_v);
        return true;
    }
}
最终发现了问题所在,并不是楼上说的那样,实际上接受ScrollArea滚动事件的应该是scrollArea->viewport()这个QWidget,所以重写的时候应该重写scrollArea->viewport()的滚动事件。
赵4老师 2019-06-17
  • 打赏
  • 举报
回复
虎头蛇尾是俗人的习惯, 有始有终是君子的操守。
Tonyimo 2017-12-14
  • 打赏
  • 举报
回复
引用 2 楼 u014430031 的回复:
重新new一个QScrollArea 对象 再重写 不要用QScrollArea.ui
我的那个帖子好像也是你回的唉,感动。。。。问题都是一样的~
橙儿稻香 2017-12-14
  • 打赏
  • 举报
回复
重新new一个QScrollArea 对象 再重写 不要用QScrollArea.ui
weixin_38838242 2017-12-13
  • 打赏
  • 举报
回复
大佬解决了吗。。?我刚好也遇到这个问题,如果解决了可以分享下经验吗

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧