sven
sven

Reputation: 1121

QResizeEvent causes SIGSEGV

My purpose is to use a class called overlay.h to add a rectangular box and text on top of a Widget (MarbleWidget). Here below is my code for the GUI. I tried to remove all unnecessary parts:

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
    setupUi(this);
}

MainWindow::~MainWindow()
{
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    overlay->resize(event->size());   //////////////// CAUSES SIGSEGV!!!!!!!!!!!!!
    event->accept();
}

void MainWindow::setupUi(QMainWindow *MainWindow)
{
    MainWindow->showMaximized();
    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    sizePolicy.setHorizontalStretch(0);
    sizePolicy.setVerticalStretch(0);
    sizePolicy.setHeightForWidth(MainWindow->sizePolicy().hasHeightForWidth());
    MainWindow->setSizePolicy(sizePolicy);
    MainWindow->setTabShape(QTabWidget::Rounded);

    QWidget *centralwidget = new QWidget(MainWindow);
    centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
    sizePolicy.setHeightForWidth(centralwidget->sizePolicy().hasHeightForWidth());
    centralwidget->setSizePolicy(sizePolicy);
    centralwidget->setLayoutDirection(Qt::LeftToRight);

    QGridLayout *gridLayout_4 = new QGridLayout(centralwidget);
    gridLayout_4->setObjectName(QString::fromUtf8("gridLayout_4"));

    QSplitter *splitter_4 = new QSplitter(centralwidget);
    splitter_4->setObjectName(QString::fromUtf8("splitter_4"));
    splitter_4->setOrientation(Qt::Horizontal);

    QTabWidget *tabWidget_2 = new QTabWidget(splitter_4);
    tabWidget_2->setObjectName(QString::fromUtf8("tabWidget_2"));
    sizePolicy.setHeightForWidth(tabWidget_2->sizePolicy().hasHeightForWidth());
    tabWidget_2->setSizePolicy(sizePolicy);
    tabWidget_2->setMaximumSize(QSize(443, 16777));
    tabWidget_2->setAutoFillBackground(true);
    tabWidget_2->setTabPosition(QTabWidget::West);
    tabWidget_2->setTabShape(QTabWidget::Rounded);
    tabWidget_2->setIconSize(QSize(30, 16));

    QWidget *tab_10 = new QWidget();
    tab_10->setObjectName(QString::fromUtf8("tab_10"));
    QGridLayout *gridLayout = new QGridLayout(tab_10);
    gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
    QVBoxLayout  *verticalLayout_4 = new QVBoxLayout();
    verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4"));
    QHBoxLayout *horizontalLayout_7 = new QHBoxLayout();
    horizontalLayout_7->setObjectName(QString::fromUtf8("horizontalLayout_7"));
    QLabel *label_3 = new QLabel(tab_10);
    label_3->setObjectName(QString::fromUtf8("label_3"));
    horizontalLayout_7->addWidget(label_3);

    verticalLayout_4->addLayout(horizontalLayout_7);
    QTreeView *treeView_4 = new QTreeView(tab_10);
    treeView_4->setObjectName(QString::fromUtf8("treeView_4"));
    QStandardItemModel *standardModel = new QStandardItemModel ;
    QStandardItem *rootNode = standardModel->invisibleRootItem();
    treeView_4->setModel(standardModel);
    verticalLayout_4->addWidget(treeView_4);
    gridLayout->addLayout(verticalLayout_4, 0, 0, 1, 1);

    tabWidget_2->addTab(tab_10, QString());
    treeView_4->raise();

    Marble::MarbleWidget* MarbleWidget = new Marble::MarbleWidget(splitter_4);

    splitter_4->addWidget(MarbleWidget);
    splitter_4->setStretchFactor(0,0);
    splitter_4->setStretchFactor(1,6);
    gridLayout_4->addWidget(splitter_4, 0, 0, 1, 1);

    MainWindow->setCentralWidget(centralwidget);
    MarbleWidget->raise();
    tabWidget_2->raise();

    overlay = new Overlay(MarbleWidget);
    overlay->raise();

    QMetaObject::connectSlotsByName(MainWindow);
} // setupUi

overlay.h

    #include <QWidget>
    #include <QPainter>

    class Overlay : public QWidget
    {
    public:
        Overlay(QWidget *parent);

    protected:
        void paintEvent(QPaintEvent *event);
    };

overlay.cpp

#include "overlay.h"

Overlay::Overlay(QWidget *parent)
: QWidget(parent)
{
    setPalette(Qt::transparent);
    setAttribute(Qt::WA_TransparentForMouseEvents);
}

void Overlay::paintEvent(QPaintEvent *event)
{
    QFont font;
    font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias);
    font.setPointSize(10);

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QColor(10, 10, 10, 255));
    painter.fillRect(QRect(50, 50, 100, 100), QColor(100, 100, 100, 120));
    painter.setFont(font);
    painter.drawText(20, 20,  "hi..............................");
}

The problem is that overlay->resize(event->size()); causes SIGSEGV when the core runs that line.

What is wrong with the code, how can I fix it?

Upvotes: 0

Views: 599

Answers (2)

sven
sven

Reputation: 1121

The problem is solved by Thiago from freenode.

He pointed that MainWindow->showMaximized(); causes resize() event to be occurred before overlay is initialized. Removing that line or moving it to after the initialization solves the problem.

Upvotes: 3

NG_
NG_

Reputation: 7181

Take a look at official documentation: QWidget, Qt5 at resize method. Here you can read

Warning: Calling resize() or setGeometry() inside resizeEvent() can lead to infinite recursion.

You are doing exactly the same. To avoid infinite recursion and respectively your SIGSEGV you can (descending order of difficulty, descending order of true-way):

  • overwrite your resizeEvent() in Overlay and comment that line in MainWindow's resizeEvent;
  • in MainWindow's resizeEvent emit signal like mainWindowSizeChanged(QSize) and connect it to your Overlay's slot;
  • do QTimer::singleShot(...) in MainWindow's resizeEvent, so it will call a given slot after a given time interval.

Upvotes: 1

Related Questions