Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Recalcutating scale factor for viewing a Pixmap in a Widget

Recalcutating scale factor for viewing a Pixmap in a Widget

Scheduled Pinned Locked Moved Solved General and Desktop
4 Posts 2 Posters 517 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • PerdrixP Offline
    PerdrixP Offline
    Perdrix
    wrote on last edited by
    #1

    In a custom widget I calculate a scale factor to apply to the Pixmap when displaying it as follows (in showEvent())

                QSize sz = size();
                qreal hScale = (qreal)sz.width()/(m_pixmap.width() + 4);
                qreal vScale = (qreal)sz.height()/(m_pixmap.height() + 4);
                m_scale = m_default_scale = std::min(hScale, vScale);
    

    and then in paintEvent() I do:

        painter.begin(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setRenderHint(QPainter::SmoothPixmapTransform);
        QPointF center(m_pixmap.width() / qreal(2), m_pixmap.height() / qreal(2));
    
    
        //painter.translate(center);
        painter.scale(m_scale, m_scale);
        //painter.translate(-center);
    
        painter.drawPixmap(QPointF(0, 0), m_pixmap);
    
    

    and that works perfectly to scale the Pixmap (which is huge) to the window which is small.

    In my resizeEvent handler I have:

        QSize oldSize = e->oldSize();
        QSize newSize = e->size();
    
        qreal hScale = (qreal)(newSize.width()) / (qreal)(oldSize.width());
        qreal vScale = (qreal)(newSize.height()) / (qreal)(oldSize.height());
    
        qreal scale = std::max(hScale, vScale);
    
        m_scale *= scale;
        m_default_scale *= scale;
        update();
    
    

    Which just doesn't work as I expected when decreasing the window size - it seems to work ok when I increase the window size. I know I'm probably in line for a face-palm moment when you enlighten me!

    What have I got wrong here please?

    1 Reply Last reply
    0
    • PerdrixP Offline
      PerdrixP Offline
      Perdrix
      wrote on last edited by Perdrix
      #4

      I have a solution that works for the resizing. Thanks for pushing me in the right direction!!

      void DSSImageWidget::resizeEvent(QResizeEvent* e)
      {
          QSize sz = e->size();
          qreal hScale = (qreal)sz.width() / (m_pixmap.width() + 4);
          qreal vScale = (qreal)sz.height() / (m_pixmap.height() + 4);
          m_scale = std::min(hScale, vScale);
      
          update();
          Inherited::resizeEvent(e);
      }
      
      void DSSImageWidget::paintEvent(QPaintEvent* event)
      {
          QPainter painter;
          painter.begin(this);
      
          :
          painter.scale(m_factor*m_scale, m_factor*m_scale);
          :
      
          painter.end();
      }
      void DSSImageWidget::wheelEvent(QWheelEvent* e)
      {
          qreal degrees = -e->angleDelta().y() / 8.0;
          qreal steps = degrees / 60.0;
          qreal factor = m_factor * std::pow(1.125, steps);
              
          m_factor = std::clamp(factor, 1.0, 5.0)
          update();
      }
      
      1 Reply Last reply
      0
      • B Offline
        B Offline
        Bonnie
        wrote on last edited by Bonnie
        #2

        I don't even know why are you doing this in the resizeEvent...
        Just copy the code in your showEvent to your resizeEvent.
        And you don't need the showEvent, resizeEvent will also be called when first shown.

        1 Reply Last reply
        0
        • PerdrixP Offline
          PerdrixP Offline
          Perdrix
          wrote on last edited by
          #3

          More explanation is in order. There's also code to zoom into the pixmap using keys/mousewheel which changes m_scale (but not m_default_scale). I would prefer to retain the zoom level (which is m_scale)when the window is resized, hence the attempt to scale the variables in resizeEvent().

          void DSSImageWidget::wheelEvent(QWheelEvent* e)
          {
              qreal degrees = -e->angleDelta().y() / 8.0;
              qreal steps = degrees / 60.0;
              qreal factor = std::pow(1.125, steps);
              m_scale *= factor;
              qreal maxscale = m_default_scale * 5.0;
              if (m_scale < m_default_scale) m_scale = m_default_scale;
              if (m_scale > maxscale) m_scale = maxscale;
              update();
          }
          

          Does that make more sense?

          1 Reply Last reply
          0
          • PerdrixP Offline
            PerdrixP Offline
            Perdrix
            wrote on last edited by Perdrix
            #4

            I have a solution that works for the resizing. Thanks for pushing me in the right direction!!

            void DSSImageWidget::resizeEvent(QResizeEvent* e)
            {
                QSize sz = e->size();
                qreal hScale = (qreal)sz.width() / (m_pixmap.width() + 4);
                qreal vScale = (qreal)sz.height() / (m_pixmap.height() + 4);
                m_scale = std::min(hScale, vScale);
            
                update();
                Inherited::resizeEvent(e);
            }
            
            void DSSImageWidget::paintEvent(QPaintEvent* event)
            {
                QPainter painter;
                painter.begin(this);
            
                :
                painter.scale(m_factor*m_scale, m_factor*m_scale);
                :
            
                painter.end();
            }
            void DSSImageWidget::wheelEvent(QWheelEvent* e)
            {
                qreal degrees = -e->angleDelta().y() / 8.0;
                qreal steps = degrees / 60.0;
                qreal factor = m_factor * std::pow(1.125, steps);
                    
                m_factor = std::clamp(factor, 1.0, 5.0)
                update();
            }
            
            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved