[英]Qt segfaults when modifying ui (c++)
I want a button I press to run a command, and then add widgets to the UI based on the command's output. 我想要一个按下的按钮来运行命令,然后根据命令的输出将小部件添加到UI。 However,
because the UI is protected in Qt and can only be modified from the main thread,
I get a segmentation fault when I try to add a widget from inside a slot activated by the command button. 但是,
由于UI受Qt保护,并且只能从主线程进行修改,因此
当我尝试从命令按钮激活的插槽中添加窗口小部件时
,
会遇到分段错误。 I tried creating a loop in the main thread checking the state of a variable that would be modified from the slot's thread, but the loop prevented the window from even being rendered, even if I forced a UI refresh for each loop cycle. 我尝试在主线程中创建一个循环,以检查将要从插槽线程修改的变量的状态,但是即使我为每个循环周期强制刷新UI,该循环也无法呈现窗口。 I've done lots of Googling, but all I can find are people who are either doing the same thing and not getting a segfault, or people who are using the slot
's thread
to modify existing widgets instead of creating a new one. 我已经做了大量的Google搜索工作,但是我所能找到的人要么是在做同样的事情而没有遇到段错误,要么是在使用slot
的线程
来修改现有的小部件而不是创建新的小部件。
The code that causes the segfault: 导致段错误的代码:
void MainWindow::on_myButton_clicked() {
...
QFrame *myFrame = new QFrame;
...
ui->myContainer->layout()->addWidget(myFrame);
[SEGFAULT]
...
}
EDIT: I fixed the original segfault (apparently QScrollAreas are made of two different components and cry if you use the wrong one). 编辑:我修复了原始的段错误(显然QScrollAreas由两个不同的组件组成,如果使用错误的组件,则会哭泣)。 But now I'm getting just about the same problem again, but for a different reason: 但是现在我又遇到了同样的问题,但是原因有所不同:
void MainWindow::on_myButton_clicked() { //from QPushButton
//run command, parse output
QFrame *myFrame = new QFrame;
ui->myContainer->layout()->addWidget(myFrame); //myContainer is the QWidget 'contents' child of a QScrollArea
QLayout *myFrameLayout = myFrame->layout();
if (myFrameLayout == NULL) { //this is what's causing the segfaults
exit(6); //random number to prove this is the cause
}
}
and the code always exits with code 6 when I press myButton. 当我按下myButton时,代码始终以代码6退出。 How can myFrameLayout be NULL if I just added myFrame to the UI? 如果我刚刚将myFrame添加到UI,myFrameLayout如何为NULL? (also, I don't see why I'm getting segfaults instead of null-pointers, but that's a different question and not one I care too much about). (同样,我不明白为什么我得到段错误而不是空指针,但这是一个不同的问题,不是我太在乎的一个问题)。
myFrame->layout()
is NULL
(as a side-note, use nullptr
instead of NULL
) because it doesn't have a layout. myFrame->layout()
为NULL
(作为附带说明,请使用nullptr
而不是NULL
),因为它没有布局。 It's in a layout, but it doesn't have one itself. 它在布局中,但本身没有布局。
ui->myContainer
has a layout. ui->myContainer
具有布局。 That layout manages myFrame
. 该布局管理myFrame
。 However, that doesn't mean that myFrame
has a layout. 但是,这并不意味着myFrame
具有布局。
If you want myFrame
to have a layout, you need to create one. 如果希望myFrame
具有布局,则需要创建一个布局。 Layouts are managing the children of widgets. 布局管理着小部件的子级。 If you wanted to add some widgets that are children of myFrame
and have a layout managing them, you'd have to create a new layout, install it on myFrame
, at which point myFrame->layout()
would return it, and then you'd create widgets and add them to myFrame->layout()
, at which point they automatically become children of myFrame
. 如果要添加一些属于myFrame
子级的小部件并具有管理它们的布局,则必须创建一个新的布局,将其安装在myFrame
上,此时myFrame->layout()
将返回它,然后您创建小部件并将它们添加到myFrame->layout()
,这时它们将自动成为myFrame
。
Right now, you're one level above. 现在,您处于较高级别。 You're adding a widget that is a child of ui->myContainer
and is managed by ui->myContainer
's layout. 您要添加一个小部件,该小部件是ui->myContainer
的子级,并由ui->myContainer
的布局管理。 Note than even though you didn't explicitly make myFrame
a child of ui->myContainer
, it is made a child when you call ui->myContainer->layout()->addWidget(myFrame)
. 请注意,即使您没有显式地将myFrame
ui->myContainer
的子代,但当您调用ui->myContainer->layout()->addWidget(myFrame)
时,它也会成为ui->myContainer->layout()->addWidget(myFrame)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.