using qactiongroup causes segfault on quit
jlgerber opened this issue · 2 comments
It seems like there is something going on here. When I introduce a QActionGroup, I get a segfault on quit. I don't see what i am doing wrong here, based on the type signatures...
I am running on os x
using qt version 5.13.2 / 5.14.0
Here is a simple repro:
#![windows_subsystem = "windows"]
use qt_core::{QString, ToolButtonStyle};
use qt_widgets::{cpp_core::CppBox, QAction, QActionGroup, QApplication, QMainWindow, QWidget};
pub fn qs<S: AsRef<str>>(input: S) -> CppBox<QString> {
QString::from_std_str(input.as_ref())
}
struct Form {
_main: CppBox<QMainWindow>,
_actiongrp: CppBox<QActionGroup>,
_action1: CppBox<QAction>,
_action2: CppBox<QAction>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
QApplication::init(|_app| unsafe {
// create main window
let mut mw = QMainWindow::new_0a();
mw.set_central_widget(QWidget::new_0a().into_ptr());
// create toolbar
let mut toolbar_ptr = mw.add_tool_bar_q_string(&qs("toolbar"));
toolbar_ptr.set_tool_button_style(ToolButtonStyle::ToolButtonTextOnly);
//create action group
let mut actiongroup = QActionGroup::new(toolbar_ptr);
let actiongroup_ptr = actiongroup.as_mut_ptr();
// create action 1
let mut action1 = QAction::from_q_object(actiongroup_ptr);
action1.set_icon_text(&qs("Foo"));
toolbar_ptr.add_action(action1.as_mut_ptr());
// create action 2
let mut action2 = QAction::from_q_object(actiongroup_ptr);
action2.set_icon_text(&qs("Bar"));
toolbar_ptr.add_action(action2.as_mut_ptr());
mw.show();
let mut _form = Form {
_main: mw,
_actiongrp: actiongroup,
_action1: action1,
_action2: action2,
};
QApplication::exec()
});
}
Looks like double free. All the content of the window is owned by it, so when CppBox<QMainWindow>
gets dropped, all containing objects are deleted as well. But CppBox<QActionGroup>
and CppBox<QAction>
will also try to delete their objects, resulting in UB. You should use into_ptr()
on a CppBox
object when you pass ownership of the object elsewhere. In case of QAction::from_q_object
, the constructed object is already owned by its parent, so you should call into_ptr()
on it immediately.
Interesting. ok that worked. I had to call into_ptr on the actions and the actiongroup. I figured that it was a double free, the ownership wasnt clear to me. Normally I call into_ptr() when i transfer ownership to qt (at least that is how i think if it). However, the docs make it sound like i own QAction...