在 QScrollArea 中的两个小部件之间切换

Switch between two widgets in QScrollArea

我有一个带有小部件的 QScrollArea select。在 selection 之后,滚动区域中的小部件应切换到另一个小部件。用户还可以 return 并再次获取 selection 小部件 select 其他内容。

可是我总是运行出错。看来这就是问题所在:

QScrollArea -> SetWidget() : [...] The widget becomes a child of the scroll area and will be destroyed when the scroll area is deleted or when a new widget is set. [...]

这很好用。 我在构造函数中添加了这样的 selection 小部件:

// Configure Window List setup
QVBoxLayout* sc_layout = new QVBoxLayout(&w_window_select);
// ... add some stuff into it ...
ui.scrollArea->setWidget(&w_window_select);

我这样更改小部件:

ui.scrollArea->setWidget(&w_window_select);
w_window_select.show();
// or
ui.scrollArea->setWidget(&lb_img);
lb_img.show();

一开始,我有一个指向 w_window_select 和 lb_img 的指针保存在我的 class 中,但是一旦我第一次切换小部件,我的旧小部件就会被删除, 我认为。我以为我可以将其更改为普通 class 成员以防止删除并且它有效,但它也崩溃了。

HEAP[Program.exe]: Invalid address specified to RtlValidateHeap( 0000000000350000, 000000000020F3C8 )

我该如何解决这个问题?每次我需要再次切换时我都可以创建小部件(它们没有那么大),但对我来说,这看起来像是一个愚蠢的解决方案。

答案是来自@G.M的评论。

Not sure I completely understand your issue but I think QScrollArea::takeWidget might prove useful. It "removes the scroll area's widget, and passes ownership of the widget to the caller".

代码:

w_window_select = ui.scrollArea->takeWidget(); 
ui.scrollArea->setWidget(lb_img); 
lb_img->show();

在切换到新的之前先获取小部件。

如果有多个小部件可以切换会怎样?您不能只使用 takeWidget() 将先前设置的小部件分配给 "its" 指针,因为您无法知道它是哪个小部件 - 小部件可以按任何顺序加载。

这是我经过一番思考后找到的可行解决方案。 A、B是QWidget指针,SA是QScrollArea指针。以下内容适用于在任意数量的 QWidget 之间切换:

// setting A for the first time
SA->setWidget(A); 
A = SA->widget(); // having the pointer for future usage

// setting B without deleting A
SA->takeWidget(); // necessary to prevent deletion of previously set widget 
SA->setWidget(B); 
B = SA->widget(); // having the pointer for future usage

// setting A again. The object is the same.
SA->takeWidget(); // necessary to prevent deletion of previously set widget 
SA->setWidget(A); 
A = SA->widget(); // having the pointer for future usage

// ...