QResizeEvent导致SIGSEGV

时间:2014-08-04 13:00:35

标签: c++ qt resize qwidget sigsegv

我的目的是使用一个名为overlay.h的类在Widget(MarbleWidget)上添加一个矩形框和文本。下面是我的GUI代码。我试图删除所有不必要的部分:

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..............................");
}

问题是当核心运行该行时overlay->resize(event->size());导致SIGSEGV

代码有什么问题,我该如何解决?

2 个答案:

答案 0 :(得分:3)

问题由freenode的Thiago解决。

他指出MainWindow->showMaximized();会导致resize()事件在overlay初始化之前发生。在初始化之后删除该行或将其移动到解决了问题。

答案 1 :(得分:1)

resize方式查看官方文档:QWidget, Qt5。在这里你可以阅读

警告: resize()内拨打setGeometry()resizeEvent()会导致无限递归。

你做的完全一样。为了避免无限递归和你的SIGSEGV你可以(难度的降序, true-way 的降序):

  • 覆盖resizeEvent()中的Overlay并在MainWindow的{​​{1}}中对该行进行评论;
  • resizeEvent的{​​{1}}发出信号,如MainWindow,并将其连接到resizeEvent的广告位;
  • mainWindowSizeChanged(QSize)的{​​{1}}中执行Overlay,因此它会在给定的时间间隔后调用给定的广告位。