简体   繁体   English

修改ui时出现Qt segfaults(C ++)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM