Visual bug when using show() on a widget above a QPushButton



  • Hey everyone, I've been trying to solve this for hours now... Here is what I'm trying to do:

    My main window has a QPushButton, when you click on it an hidden widget appears above all the other widgets. The newly shown widget contains a single QWidget displaying an image. The problem is, the QPushButton seems to interfer with the QWidget display. Here is the result:

    !http://oi57.tinypic.com/111qo84.jpg(Visual bug - before resize)!

    Something interesting to note, after resize, the display corrects itself:

    !http://oi57.tinypic.com/125t98j.jpg(Display corrected - after resize)!

    Here is my code (window.cpp and imagelabel.cpp are probably the only important files, but I've put all others if you want to compile it yourself):

    main.cpp

    @#include <QApplication>
    #include <QtWidgets>
    #include "window.h"

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);

    Window w;
    w.show();
    
    return app.exec&#40;&#41;;
    

    }@

    window.h
    @#ifndef WINDOW
    #define WINDOW

    #include <QtWidgets>
    #include <string>
    #include <QVBoxLayout>
    #include <QFrame>
    #include <QDebug>

    #include "imagelabel.h"

    class Window : public QMainWindow
    {
    Q_OBJECT

    public:
    Window();
    
    void resizeEvent(QResizeEvent *event);
    void moveEvent(QMoveEvent *event);
    
    private:
    QWidget *centralWidget;
    QVBoxLayout *mainLayout;
    QVBoxLayout *overlayLayout;
    QWidget *cardPicker;
    

    };

    #endif // WINDOW@

    imagelabel.h
    @#ifndef IMAGELABEL
    #define IMAGELABEL

    #include <QWidget>
    #include <QPainter>
    #include <QPaintEvent>
    #include <QDebug>

    class ImageLabel : public QWidget
    {
    Q_OBJECT

    public:
    explicit ImageLabel(QWidget parent = 0);
    const QPixmap
    pixmap() const;

    public slots:
    void setPixmap(const QPixmap&);

    protected:
    void paintEvent(QPaintEvent *);

    private:
    QPixmap pix;
    };

    #endif // IMAGELABEL@

    imagelabel.cpp
    @#include "imagelabel.h"

    ImageLabel::ImageLabel(QWidget *parent) :
    QWidget(parent)
    {
    }

    void ImageLabel::paintEvent(QPaintEvent *event)
    {
    QWidget::paintEvent(event);

    if (pix.isNull())
        return;
    
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    
    QSize pixSize = pix.size();
    pixSize.scale(event->rect().size(), Qt::KeepAspectRatio);
    
    QPixmap scaledPix = pix.scaled(pixSize,
                                   Qt::KeepAspectRatio,
                                   Qt::SmoothTransformation
                                   );
    
    painter.drawPixmap(QPoint(), scaledPix);
    

    }

    const QPixmap* ImageLabel::pixmap() const
    {
    return &pix;
    }

    void ImageLabel::setPixmap (const QPixmap &pixmap)
    {
    pix = pixmap;
    }
    @

    window.cpp
    @#include "window.h"

    Window::Window()
    {
    setMinimumSize(475, 325);

    centralWidget = new QWidget;
    setCentralWidget(centralWidget);
    
    // Default central widget
    mainLayout = new QVBoxLayout(centralWidget);
    
    // Main application buttons
    QPushButton *openCPButton = new QPushButton("Open CardPicker");
    QPushButton *quitButton = new QPushButton("Quit");
    QObject::connect(quitButton, SIGNAL(clicked()), qApp, SLOT(quit()));
    
    mainLayout->addWidget(openCPButton);
    mainLayout->addWidget(quitButton);
    
    
    // The pop up widget that appears when "openCPButton" is clicked
    cardPicker = new QWidget(centralWidget);
    cardPicker->hide();
    
    QObject::connect(openCPButton, SIGNAL(clicked()), cardPicker, SLOT(show()));
    
    overlayLayout = new QVBoxLayout(cardPicker);
    QWidget *m_cpFrame = new QLabel();
    m_cpFrame->setStyleSheet(" QLabel { background-color : white;"
                   "color : blue; border: 2px solid black;}");
    
    overlayLayout->addWidget(m_cpFrame);
    
    QVBoxLayout *cardsLayout = new QVBoxLayout(m_cpFrame);
    ImageLabel *card = new ImageLabel();
    card->setPixmap(QPixmap("Images/cards/2c.png"));
    
    cardsLayout->addWidget(card);
    
    QPushButton *closeCPButton = new QPushButton("Close");
    QObject::connect(closeCPButton, SIGNAL(clicked()), cardPicker, SLOT(hide()));
    cardsLayout->addWidget(closeCPButton);
    

    }

    void Window::resizeEvent(QResizeEvent *event)
    {
    cardPicker->resize(this->width()*0.9, this->height()*0.6);
    event->accept();
    }

    void Window::moveEvent(QMoveEvent *)
    {
    cardPicker->move(width()*0.05, height()*0.2);
    }
    @

    I've tried this code on multiples compilers and it's always the same. I'm on Windows 8.1, Qt5.4.0. Thanks for your help!


  • Lifetime Qt Champion

    Hi,

    Maybe a silly question but why don't you use QLabel ?



  • I needed to resize my image and keep its aspect ratio. When I googled that I ended up finding this stackoverflow question and answer:

    "How do I make an image resize to scale in Qt?":http://stackoverflow.com/questions/14107144/how-do-i-make-an-image-resize-to-scale-in-qt

    The code seemed to make sense, and while the display bug probably comes from there, I'm not sure what I should change nor why is it not working?


  • Lifetime Qt Champion

    Does it also happen if you run your card picker solo ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.