我的实际用例非常重要,所以我提供了一个重现分段错误的小例子:
我有继承QScrollArea的类CustomScrollArea:
customscrollarea.h
class CustomScrollArea : public QScrollArea
{
Q_OBJECT
public:
explicit WarxingScrollArea(QWidget* parent=0);
void segFaultThrowingMethod();
private:
QLabel* dynamicallyCreatedLabel;
};
customscrollarea.cpp
CustomScrollArea::CustomScrollArea(QWidget* parent) : QScrollArea(parent)
{
dynamicallyCreatedLabel = new QLabel;
setWidget(dynamicallyCreatedLabel);
//this call will _not_ cause a seg fault
segFaultThrowingMethod();
}
void CustomScrollArea::segFaultThrowingMethod()
{
dynamicallyCreatedLabel->setText("Some text");
}
我有一个MainWindow类,其中包含以下内容:
mainwindow.h
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//this call will cause a seg fault
ui->customScrollArea->segFaultThrowingMethod();
}
MainWindow::~MainWindow()
{
delete ui;
}
MainWindow的.ui文件包含一个提升为CustomQScrollArea的QScrollArea。它的名字是“customScrollArea”。
当我启动应用程序时,CustomScrollArea :: segFaultThrowingMethod()的第一次调用发生在CustomScrollArea的Ui :: MainWindow :: customScrollArea的构造函数中,并且无事故地传递。但是,当MainWindow调用ui-> customScrollArea-> segFaultThrowingMethod()时,会发生分段错误。
请注意,分段错误不是由于CustomScrollArea :: dynamicCreatedLabel为空(如建议的here)。我得到的最好线索是,如果MainWindow动态实例化CustomScrollArea而不是从Ui :: MainWindow获取它,则不会发生此问题。但是,我希望能够在Qt Designer中使用QScrollAreas提升为CustomScrollAreas。
感谢您的帮助!
答案 0 :(得分:1)
Qt Designer会自动为任何滚动区域创建内部窗口小部件。默认情况下,此窗口小部件称为“scrollAreaWidgetContents”,在Qt Designer的窗口小部件树中可见。 Designer生成的Ui::MainWindow
类为您创建CustomScrollArea并执行setWidget
来设置其内容。调用CustomScrollArea构造函数后,此操作在setupUi
中发生。但QScrollArea获得其内部窗口小部件的所有权。调用setWidget
时,前一个滚动区域的内部窗口小部件(如果有)将被解除并销毁。因此,在setWidget
内调用setupUi
会导致先前创建的QLabel被破坏,并且dynamicallyCreatedLabel
指针变为无效。
无法在Qt Designer中删除“scrollAreaWidgetContents”。解决方法是向窗体添加一个窗口小部件并将其提升为CustomScrollArea类。 Qt Designer不会知道CustomScrollArea实际上是QScrollArea并且不会自己调用setWidget
。唯一的副作用是您将无法在Qt Designer中设置滚动区域特定属性并访问其插槽。但是你可以从代码中做到这一点,所以这不是一个大问题。