在 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
// ...
我有一个带有小部件的 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
// ...