Thanks for the help both! This is the working code to finally make multiple pages in Qt!
#![windows_subsystem = "windows"]
//Importing the required stuff
use cpp_core::{Ptr, Ref, StaticUpcast, CppDeletable};
use qt_core::{qs, slot, ContextMenuPolicy, QBox, QObject, QPoint, SlotNoArgs, QString};
use qt_widgets::{
QAction, QApplication, QLineEdit, QMenu, QMessageBox, QPushButton, QLabel, QTableWidget,
QTableWidgetItem, QVBoxLayout, QWidget, SlotOfQPoint, SlotOfQTableWidgetItemQTableWidgetItem,
QWidgetItem,
};
use std::rc::Rc;
use std::cell::RefCell;
//Struct for Main window
struct MainWindow {
widget: QBox<QWidget>,
button: QBox<QPushButton>,
}
//From form-struct to base-struct ???
impl StaticUpcast<QObject> for MainWindow {
unsafe fn static_upcast(ptr: Ptr<Self>) -> Ptr<QObject> {
ptr.widget.as_ptr().static_upcast()
}
}
//Implementing functions for MainWindow
impl MainWindow {
//Defining all the graphical elements in MainWindow
//Returns the MainWindow in a Reference Counted Smart Pointer so it can have multiple owners
//and doesn't get destroyed until it has no owners anymore
fn new() -> Rc<MainWindow> {
unsafe {
//Widget
let widget = QWidget::new_0a();
let layout = QVBoxLayout::new_1a(&widget);
//Label
let label = QLabel::new();
label.set_text(&qs("Label A!"));
layout.add_widget(&label);
//Button
let button = QPushButton::from_q_string(&qs("Click me."));
layout.add_widget(&button);
widget.show();
let this = Rc::new(Self {
widget,
button,
});
this.init();
this
}
}
//Binding functions/slots to elements etc
unsafe fn init(self: &Rc<Self>) {
self.button
.clicked()
.connect(&self.slot_build_option_a());
}
//Slots/Functions for buttons
//
//Function to build the second screen
#[slot(SlotNoArgs)]
unsafe fn build_option_a(self: &Self) {
//DELETING all buttons, labels,...
for i in 0..self.widget.layout().count() {
let it = self.widget.layout().take_at(i);
if let Some(wi) = it.dynamic_cast::<QWidgetItem>().as_ref() {
wi.widget().delete();
}
}
self.widget.layout().to_box();
self.button.delete(); //Somehow needed to delete the button as well, maybe because it's defined as a struct property?
//Building new layout etc
let layout = QVBoxLayout::new_1a(&self.widget);
//Label
let label = QLabel::new();
label.set_text(&qs("Label B!"));
layout.add_widget(&label);
}
}
fn main() {
QApplication::init(|_| unsafe {
let _mw = MainWindow::new();
QApplication::exec()
})
}
I only don't understand line 80. I had to remove that button separately, why didn't it get deleted in the for loop? Because of it's longer lifetime because it's defined as a struct property?
@Riateche And the issue with StackedLayout is that I have no idea on how to implement that.
If you look at this page they give some C++ examples. In those examples the stackedLayout is kinda the parent holding the widgets as children. So for each page I'd have to make a different widget. But in Rust I need to upcast those widgets to keep them visible, but I can only upcast one
//From form-struct to base-struct ???
impl StaticUpcast<QObject> for MainWindow {
unsafe fn static_upcast(ptr: Ptr<Self>) -> Ptr<QObject> {
ptr.widget.as_ptr().static_upcast();
//I tried this but didn't work (because of the return type of the function of course):
//ptr.widget_b.as_ptr().static_upcast()
}
}
So I thought I'd make a vector of widgets in the struct MainWindow, but also that didn't work.
Tl;dr, I actually have no idea on how to make my struct MainWindow and what properties to use for it to work with a stackedlayout holding multiple widgets.