QResizeEvent 导致 SIGSEGV
Posted
技术标签:
【中文标题】QResizeEvent 导致 SIGSEGV【英文标题】:QResizeEvent causes SIGSEGV 【发布时间】:2014-08-04 13:00:35 【问题描述】:我的目的是使用一个名为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
。
代码有什么问题,我该如何解决?
【问题讨论】:
不是 100% 确定,但看起来调整叠加层的大小会导致主窗口也被调整大小。由于这发生在调整大小处理程序中,因此很可能会递归调用它并最终导致堆栈溢出。 @Frédéric Hamidi,感谢您的解释。您是否看到任何阻止 resize() 调整主窗口大小的方法/技巧? 我对 Qt 不够熟悉,无法为您提供灵丹妙药。我会仔细检查覆盖的新大小——也许你必须减去一些边框宽度以防止父级也调整大小。您还可以使用布尔成员变量保护您的调整大小处理程序,以防止它在调整叠加层大小时重新进入,但我不确定结果是否适合您。 当我通过调试器运行代码时,它会在第一次到达'overlay->resize(event->size())'时获取SIGSEGV Kuba Ober,我把基本布局留在了代码上,已经去掉了很多不必要的东西。代码长了 5 倍。随意编辑问题。顺便说一句,您对布局的回答让我受益匪浅,感谢您的帖子。 【参考方案1】:问题由freenode的Thiago
解决。
他指出MainWindow->showMaximized();
导致resize()
事件在overlay
初始化之前发生。删除该行或将其移至初始化后即可解决问题。
【讨论】:
如果你在调试器下运行它,问题就会得到解决。回溯可以查明问题所在。调用堆栈包含:setupUi
、showMaximized
、resizeEvent
。或者,如果您按照应有的方式将代码最小化,您将删除showMaximized
行,问题就会消失。所以,你忽略了解决它的两种方法:/【参考方案2】:
查看官方文档:QWidget, Qt5resize
方法。在这里你可以阅读
警告:在resizeEvent()
内调用resize()
或setGeometry()
会导致无限递归。
你做的完全一样。为了避免无限递归,您可以分别使用 SIGSEGV(难度降序,true-way 降序):
在Overlay
中覆盖您的resizeEvent()
并在MainWindow
的resizeEvent
中评论该行;
在MainWindow
的resizeEvent
发出类似mainWindowSizeChanged(QSize)
的信号并将其连接到Overlay
的插槽;
在MainWindow
的resizeEvent
中执行QTimer::singleShot(...)
,所以它会在给定的时间间隔后调用给定的槽。
【讨论】:
仅当您为同一个小部件调用resize
时才适用。在这种情况下不适用。以上是关于QResizeEvent 导致 SIGSEGV的主要内容,如果未能解决你的问题,请参考以下文章
qt中怎么设置按钮的位置 固定在右上角 最大化和普通大小都在右上角
amazon redshift 并发写入导致插入记录,导致重复
FileHandler 创建会导致 NoSuchFileException 导致缺少 .lck