Skip to main content

Menu

Struct Menu 

Source
pub struct Menu { /* private fields */ }
Expand description

A drop-down menu containing actions.

Menu uses a builder pattern: call Menu::new to obtain a MenuBuilder, then call .build().

§Example

use qtrs::{Menu, MenuBar};

let mut file_menu = Menu::new("File")
    .action("New", || println!("New file"))
    .action("Open", || println!("Open file"))
    .build();

Implementations§

Source§

impl Menu

Source

pub fn new(title: impl Into<String>) -> MenuBuilder

Start building a new menu.

Examples found in repository?
examples/demo/demo.rs (line 215)
7fn main() {
8    let app = Application::new();
9
10    // ============================================================
11    // Main window
12    // ============================================================
13    let window = Widget::new()
14        .title("qtrs Widget Gallery")
15        .size(900, 700)
16        .build();
17
18    // ============================================================
19    // Main layout
20    // ============================================================
21    let mut main_layout = VBoxLayout::with_parent(&window);
22    main_layout.set_spacing(10);
23    main_layout.set_contents_margins(15, 15, 15, 15);
24
25    // ============================================================
26    // Title
27    // ============================================================
28    let title_label = Label::new("\n=== qtrs Widget Gallery ===")
29        .parent(&window)
30        .build();
31    main_layout.add_widget(Box::new(title_label));
32
33    // ============================================================
34    // Section 1: Buttons
35    // ============================================================
36    let group1 = GroupBox::new("Buttons")
37        .parent(&window)
38        .build();
39    let mut g1_layout = VBoxLayout::with_parent(&group1);
40    g1_layout.set_spacing(8);
41
42    // PushButton
43    let btn = PushButton::new("Click Me")
44        .on_clicked(|| println!("[LOG] Button clicked"))
45        .parent(&group1)
46        .build();
47    g1_layout.add_widget(Box::new(btn));
48
49    // CheckBox
50    let cb = CheckBox::new("Check me")
51        .checked(false)
52        .on_toggled(|checked| println!("[LOG] CheckBox: {}", checked))
53        .parent(&group1)
54        .build();
55    g1_layout.add_widget(Box::new(cb));
56
57    // RadioButton group
58    let rb1_label = Label::new("Radio Group (click to log):").parent(&group1).build();
59    g1_layout.add_widget(Box::new(rb1_label));
60
61    let rb1 = RadioButton::new("Option A")
62        .checked(true)
63        .on_toggled(|checked| {
64            if checked {
65                println!("[LOG] Radio selected: A");
66            }
67        })
68        .parent(&group1)
69        .build();
70    g1_layout.add_widget(Box::new(rb1));
71
72    let rb2 = RadioButton::new("Option B")
73        .checked(false)
74        .on_toggled(|checked| {
75            if checked {
76                println!("[LOG] Radio selected: B");
77            }
78        })
79        .parent(&group1)
80        .build();
81    g1_layout.add_widget(Box::new(rb2));
82
83    let rb3 = RadioButton::new("Option C")
84        .checked(false)
85        .on_toggled(|checked| {
86            if checked {
87                println!("[LOG] Radio selected: C");
88            }
89        })
90        .parent(&group1)
91        .build();
92    g1_layout.add_widget(Box::new(rb3));
93
94    main_layout.add_widget(Box::new(group1));
95
96    // ============================================================
97    // Section 2: Input widgets
98    // ============================================================
99    let group2 = GroupBox::new("Inputs")
100        .parent(&window)
101        .build();
102    let mut g2_layout = VBoxLayout::with_parent(&group2);
103    g2_layout.set_spacing(8);
104
105    // LineEdit
106    let edit = LineEdit::new("Type text here...")
107        .on_return_pressed(|| println!("[LOG] LineEdit return pressed"))
108        .parent(&group2)
109        .build();
110    g2_layout.add_widget(Box::new(edit));
111
112    // ComboBox
113    let mut combo = ComboBox::new()
114        .items(&["Item 1", "Item 2", "Item 3", "Item 4"])
115        .on_current_text_changed(|| println!("[LOG] ComboBox text changed"))
116        .parent(&group2)
117        .build();
118    combo.connect_current_index_changed(|idx| {
119        println!("[LOG] ComboBox index: {}", idx);
120    });
121    g2_layout.add_widget(Box::new(combo));
122
123    // TextEdit
124    let text_edit = TextEdit::new()
125        .placeholder("Write multi-line text here...")
126        .on_text_changed(|| println!("[LOG] TextEdit content changed"))
127        .parent(&group2)
128        .build();
129    g2_layout.add_widget(Box::new(text_edit));
130
131    main_layout.add_widget(Box::new(group2));
132
133    // ============================================================
134    // Section 3: Value widgets (Slider + ProgressBar + SpinBox)
135    // ============================================================
136    let group3 = GroupBox::new("Values")
137        .parent(&window)
138        .build();
139    let mut g3_layout = VBoxLayout::with_parent(&group3);
140    g3_layout.set_spacing(8);
141
142    // ProgressBar
143    let bar = ProgressBar::new()
144        .range(0, 100)
145        .value(50)
146        .format("%p%")
147        .parent(&group3)
148        .build();
149    g3_layout.add_widget(Box::new(bar));
150
151    // Slider
152    let slider = Slider::horizontal()
153        .range(0, 100)
154        .on_value_changed(|v| {
155            println!("[LOG] Slider value: {}", v);
156        })
157        .parent(&group3)
158        .build();
159    slider.set_value(50);
160    g3_layout.add_widget(Box::new(slider));
161
162    // SpinBox
163    let spin = SpinBox::new()
164        .range(0, 100)
165        .value(50)
166        .suffix(" units")
167        .on_value_changed(|v| {
168            println!("[LOG] SpinBox value: {}", v);
169        })
170        .parent(&group3)
171        .build();
172    g3_layout.add_widget(Box::new(spin));
173
174    main_layout.add_widget(Box::new(group3));
175
176    // ============================================================
177    // Section 4: TabWidget
178    // ============================================================
179    let mut tabs = TabWidget::new()
180        .on_current_changed(|idx| println!("[LOG] Tab changed to: {}", idx))
181        .parent(&window)
182        .build();
183
184    // Tab 1: Simple text
185    let tab1 = Widget::new().parent(&tabs).build();
186    let mut tab1_layout = VBoxLayout::with_parent(&tab1);
187    let tab1_label = Label::new("This is Tab 1").parent(&tab1).build();
188    tab1_layout.add_widget(Box::new(tab1_label));
189    tabs.add_tab(Box::new(tab1), "Tab 1");
190
191    // Tab 2: CheckBoxes
192    let tab2 = Widget::new().parent(&tabs).build();
193    let mut tab2_layout = VBoxLayout::with_parent(&tab2);
194    let cb1 = CheckBox::new("Option X").parent(&tab2).build();
195    let cb2 = CheckBox::new("Option Y").parent(&tab2).build();
196    tab2_layout.add_widget(Box::new(cb1));
197    tab2_layout.add_widget(Box::new(cb2));
198    tabs.add_tab(Box::new(tab2), "Tab 2");
199
200    // Tab 3: Button
201    let tab3 = Widget::new().parent(&tabs).build();
202    let mut tab3_layout = VBoxLayout::with_parent(&tab3);
203    let btn_tab3 = PushButton::new("Tab 3 Button")
204        .on_clicked(|| println!("[LOG] Tab 3 button clicked"))
205        .parent(&tab3)
206        .build();
207    tab3_layout.add_widget(Box::new(btn_tab3));
208    tabs.add_tab(Box::new(tab3), "Tab 3");
209
210    main_layout.add_widget(Box::new(tabs));
211
212    // ============================================================
213    // Section 5: Menu + MenuBar
214    // ============================================================
215    let file_menu = Menu::new("File")
216        .action("New", || println!("[LOG] Menu: New"))
217        .action("Open", || println!("[LOG] Menu: Open"))
218        .action("Save", || println!("[LOG] Menu: Save"))
219        .action("Exit", || {
220            println!("[LOG] Menu: Exit");
221            std::process::exit(0);
222        })
223        .parent(&window)
224        .build();
225
226    let edit_menu = Menu::new("Edit")
227        .action("Copy", || println!("[LOG] Menu: Copy"))
228        .action("Paste", || println!("[LOG] Menu: Paste"))
229        .action("Cut", || println!("[LOG] Menu: Cut"))
230        .parent(&window)
231        .build();
232
233    // Help menu: use a raw pointer to avoid move semantics
234    // We need to pass &window to dialog::information, but we can't move it.
235    // Use a reference counted wrapper, or just pass None as parent.
236    // For simplicity, we pass None (dialog will be centered on screen).
237    let help_menu = Menu::new("Help")
238        .action("About", || {
239            println!("[LOG] Menu: About");
240            dialog::information(
241                None,  // No parent window, dialog appears centered on screen
242                "About",
243                "qtrs Widget Gallery\nVersion 0.2.2\n\nAll widgets test",
244            );
245        })
246        .parent(&window)
247        .build();
248
249    // MenuBar: use builder pattern
250    let _menubar = MenuBar::new()
251        .add_menu(file_menu)
252        .add_menu(edit_menu)
253        .add_menu(help_menu)
254        .parent(&window)
255        .build();
256
257    // ============================================================
258    // Bottom buttons: Dialogs
259    // ============================================================
260    let mut bottom_layout = HBoxLayout::new();
261    bottom_layout.set_spacing(10);
262
263    let info_btn = PushButton::new("Show Info")
264        .on_clicked(|| {
265            println!("[LOG] Info dialog shown");
266            dialog::information(None, "Info", "This is an information dialog");
267        })
268        .parent(&window)
269        .build();
270    bottom_layout.add_widget(Box::new(info_btn));
271
272    let warn_btn = PushButton::new("Show Warning")
273        .on_clicked(|| {
274            println!("[LOG] Warning dialog shown");
275            dialog::warning(None, "Warning", "This is a warning dialog");
276        })
277        .parent(&window)
278        .build();
279    bottom_layout.add_widget(Box::new(warn_btn));
280
281    let ask_btn = PushButton::new("Ask Question")
282        .on_clicked(|| {
283            println!("[LOG] Question dialog shown");
284            let answer = dialog::question(None, "Question", "Are you sure?");
285            println!("[LOG] Answer: {}", if answer { "Yes" } else { "No" });
286        })
287        .parent(&window)
288        .build();
289    bottom_layout.add_widget(Box::new(ask_btn));
290
291    let mut bottom_widget = Widget::new().parent(&window).build();
292    bottom_widget.set_hlayout(bottom_layout.layout_ptr());
293    main_layout.add_widget(Box::new(bottom_widget));
294
295    // ============================================================
296    // Status bar
297    // ============================================================
298    let status_label = Label::new("Status: Ready - All widgets loaded")
299        .parent(&window)
300        .build();
301    main_layout.add_widget(Box::new(status_label));
302
303    // ============================================================
304    // Show window and run
305    // ============================================================
306    window.show();
307    println!("[LOG] Application started - all widgets loaded");
308    println!("[LOG] Interact with widgets to see logs in terminal");
309
310    app.exec();
311}
Source

pub fn menu_ptr(&self) -> *mut QMenu

Get the raw menu pointer for use with [MenuBar::add_menu].

Trait Implementations§

Source§

impl AsWidget for Menu

Source§

fn widget_ptr(&self) -> *mut QWidget

Return the underlying QWidget* pointer. Read more
Source§

fn set_has_parent(&mut self)

Mark this widget as having a Qt parent. Read more
Source§

impl Drop for Menu

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl !Send for Menu

§

impl !Sync for Menu

§

impl Freeze for Menu

§

impl RefUnwindSafe for Menu

§

impl Unpin for Menu

§

impl UnsafeUnpin for Menu

§

impl UnwindSafe for Menu

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.