Skip to main content

GroupBox

Struct GroupBox 

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

A group box with a title, used to group related widgets.

GroupBox uses a builder pattern: call GroupBox::new to obtain a Builder, then call .build().

§Example

use qtrs::{GroupBox, VBoxLayout, RadioButton};

let group = GroupBox::new("Options")
    .build();

// Add radio buttons to the group...

Implementations§

Source§

impl GroupBox

Source

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

Start building a new group box.

Examples found in repository?
examples/demo/demo.rs (line 40)
10fn main() {
11    let app = Application::new();
12
13    // ============================================================
14    // Main window
15    // ============================================================
16    let window = Widget::new()
17        .title("qtrs Widget Gallery")
18        .icon("assets/icon.png")
19        .size(900, 700)
20        .build();
21
22    // ============================================================
23    // Main layout
24    // ============================================================
25    let mut main_layout = VBoxLayout::with_parent(&window);
26    main_layout.set_spacing(10);
27    main_layout.set_contents_margins(15, 15, 15, 15);
28
29    // ============================================================
30    // Title
31    // ============================================================
32    let title_label = Label::new("\nqtrs Widget Gallery")
33        .parent(&window)
34        .build();
35    main_layout.add_widget(Box::new(title_label));
36    
37    // ============================================================
38    // Section 1: Buttons
39    // ============================================================
40    let group1 = GroupBox::new("Buttons")
41        .parent(&window)
42        .build();
43    let mut g1_layout = VBoxLayout::with_parent(&group1);
44    g1_layout.set_spacing(8);
45
46    // PushButton
47    let btn = PushButton::new("Click Me")
48        .on_clicked(|| println!("[LOG] Button clicked"))
49        .parent(&group1)
50        .build();
51    g1_layout.add_widget(Box::new(btn));
52
53    // CheckBox
54    let cb = CheckBox::new("Check me")
55        .checked(false)
56        .on_toggled(|checked| println!("[LOG] CheckBox: {}", checked))
57        .parent(&group1)
58        .build();
59    g1_layout.add_widget(Box::new(cb));
60
61    // RadioButton group
62    let rb1_label = Label::new("Radio Group (click to log):").parent(&group1).build();
63    g1_layout.add_widget(Box::new(rb1_label));
64
65    let rb1 = RadioButton::new("Option A")
66        .checked(true)
67        .on_toggled(|checked| {
68            if checked {
69                println!("[LOG] Radio selected: A");
70            }
71        })
72        .parent(&group1)
73        .build();
74    g1_layout.add_widget(Box::new(rb1));
75
76    let rb2 = RadioButton::new("Option B")
77        .checked(false)
78        .on_toggled(|checked| {
79            if checked {
80                println!("[LOG] Radio selected: B");
81            }
82        })
83        .parent(&group1)
84        .build();
85    g1_layout.add_widget(Box::new(rb2));
86
87    let rb3 = RadioButton::new("Option C")
88        .checked(false)
89        .on_toggled(|checked| {
90            if checked {
91                println!("[LOG] Radio selected: C");
92            }
93        })
94        .parent(&group1)
95        .build();
96    g1_layout.add_widget(Box::new(rb3));
97
98    main_layout.add_widget(Box::new(group1));
99
100    // ============================================================
101    // Section 2: Input widgets
102    // ============================================================
103    let group2 = GroupBox::new("Inputs")
104        .parent(&window)
105        .build();
106    let mut g2_layout = VBoxLayout::with_parent(&group2);
107    g2_layout.set_spacing(8);
108
109    // LineEdit
110    let edit = LineEdit::new("Type text here...")
111        .on_return_pressed(|| println!("[LOG] LineEdit return pressed"))
112        .parent(&group2)
113        .build();
114    g2_layout.add_widget(Box::new(edit));
115
116    // ComboBox
117    let mut combo = ComboBox::new()
118        .items(&["Item 1", "Item 2", "Item 3", "Item 4"])
119        .on_current_text_changed(|| println!("[LOG] ComboBox text changed"))
120        .parent(&group2)
121        .build();
122    combo.connect_current_index_changed(|idx| {
123        println!("[LOG] ComboBox index: {}", idx);
124    });
125    g2_layout.add_widget(Box::new(combo));
126
127    // TextEdit
128    let text_edit = TextEdit::new()
129        .placeholder("Write multi-line text here...")
130        .on_text_changed(|| println!("[LOG] TextEdit content changed"))
131        .parent(&group2)
132        .build();
133    g2_layout.add_widget(Box::new(text_edit));
134
135    main_layout.add_widget(Box::new(group2));
136
137    // ============================================================
138    // Section 3: Full Bidirectional Sync (Slider ↔ SpinBox → ProgressBar)
139    // ============================================================
140    let group3 = GroupBox::new("Values")
141        .parent(&window)
142        .build();
143    let mut g3_layout = VBoxLayout::with_parent(&group3);
144    g3_layout.set_spacing(8);
145
146    // Build all widgets first (before adding to layout)
147    let bar = ProgressBar::new()
148        .range(0, 100)
149        .value(50)
150        .format("%p%")
151        .parent(&group3)
152        .build();
153
154    let slider = Slider::horizontal()
155        .range(0, 100)
156        .parent(&group3)
157        .build();
158    slider.set_value(50);
159
160    let spin = SpinBox::new()
161        .range(0, 100)
162        .value(50)
163        .suffix(" units")
164        .parent(&group3)
165        .build();
166
167    // ============================================================
168    // ALL connections BEFORE adding to layout
169    // ============================================================
170
171    // Slider → SpinBox (bidirectional)
172    slider.connect(
173        VALUE_CHANGED,
174        &spin,
175        SET_VALUE,
176        ConnType::Queued,
177    );
178
179    // SpinBox → Slider (bidirectional)
180    spin.connect(
181        VALUE_CHANGED,
182        &slider,
183        SET_VALUE,
184        ConnType::Queued,
185    );
186
187    // Slider → ProgressBar
188    slider.connect(
189        VALUE_CHANGED,
190        &bar,
191        SET_VALUE,
192        ConnType::Auto,
193    );
194
195    // SpinBox → ProgressBar
196    spin.connect(
197        VALUE_CHANGED,
198        &bar,
199        SET_VALUE,
200        ConnType::Auto,
201    );
202
203    // ============================================================
204    // NOW add widgets to layout (after all connections)
205    // ============================================================
206    g3_layout.add_widget(Box::new(bar));
207    g3_layout.add_widget(Box::new(slider));
208    g3_layout.add_widget(Box::new(spin));
209
210    main_layout.add_widget(Box::new(group3));
211
212    // ============================================================
213    // Section 4: TabWidget
214    // ============================================================
215    let mut tabs = TabWidget::new()
216        .on_current_changed(|idx| println!("[LOG] Tab changed to: {}", idx))
217        .parent(&window)
218        .build();
219
220    // Tab 1: Simple text
221    let tab1 = Widget::new().parent(&tabs).build();
222    let mut tab1_layout = VBoxLayout::with_parent(&tab1);
223    let tab1_label = Label::new("This is Tab 1").parent(&tab1).build();
224    tab1_layout.add_widget(Box::new(tab1_label));
225    tabs.add_tab(Box::new(tab1), "Tab 1");
226
227    // Tab 2: CheckBoxes
228    let tab2 = Widget::new().parent(&tabs).build();
229    let mut tab2_layout = VBoxLayout::with_parent(&tab2);
230    let cb1 = CheckBox::new("Option X").parent(&tab2).build();
231    let cb2 = CheckBox::new("Option Y").parent(&tab2).build();
232    tab2_layout.add_widget(Box::new(cb1));
233    tab2_layout.add_widget(Box::new(cb2));
234    tabs.add_tab(Box::new(tab2), "Tab 2");
235
236    // Tab 3: Button
237    let tab3 = Widget::new().parent(&tabs).build();
238    let mut tab3_layout = VBoxLayout::with_parent(&tab3);
239    let btn_tab3 = PushButton::new("Tab 3 Button")
240        .on_clicked(|| println!("[LOG] Tab 3 button clicked"))
241        .parent(&tab3)
242        .build();
243    tab3_layout.add_widget(Box::new(btn_tab3));
244    tabs.add_tab(Box::new(tab3), "Tab 3");
245
246    main_layout.add_widget(Box::new(tabs));
247
248    // ============================================================
249    // Section 5: Menu + MenuBar
250    // ============================================================
251    let file_menu = Menu::new("File")
252        .action("New", || println!("[LOG] Menu: New"))
253        .action("Open", || {
254            println!("[LOG] Menu: Open");
255            if let Some(path) = FileDialog::open_file(
256                None,  // No parent needed
257                "Select a file",
258                "",
259                "All Files (*.*);;Text Files (*.txt);;Images (*.png *.jpg *.bmp)"
260            ) {
261                println!("[LOG] File selected: {}", path);
262            } else {
263                println!("[LOG] File dialog cancelled");
264            }
265        })
266        .action("Save", || {
267            println!("[LOG] Menu: Save");
268            if let Some(path) = FileDialog::select_directory(
269                None, "Select a directory to save", 
270                "",
271            ) {
272                println!("[LOG] Directory selected: {}", path);
273            } else {
274                println!("[LOG] File dialog cancelled");
275            }
276        })
277        .action("Exit", || {
278            println!("[LOG] Menu: Exit");
279            std::process::exit(0);
280        })
281        .parent(&window)
282        .build();
283
284    let edit_menu = Menu::new("Edit")
285        .action("Copy", || println!("[LOG] Menu: Copy"))
286        .action("Paste", || println!("[LOG] Menu: Paste"))
287        .action("Cut", || println!("[LOG] Menu: Cut"))
288        .parent(&window)
289        .build();
290
291    let help_menu = Menu::new("Help")
292        .action("About", || {
293            println!("[LOG] Menu: About");
294            dialog::information(
295                None,  // No parent needed
296                "About",
297                "qtrs Widget Gallery\nVersion 0.2.5\n\nAll widgets test",
298            );
299        })
300        .parent(&window)
301        .build();
302
303    let _menubar = MenuBar::new()
304        .add_menu(file_menu)
305        .add_menu(edit_menu)
306        .add_menu(help_menu)
307        .parent(&window)
308        .build();
309
310    // ============================================================
311    // Bottom buttons: Dialogs
312    // ============================================================
313    let mut bottom_layout = HBoxLayout::new();
314    bottom_layout.set_spacing(10);
315
316    let info_btn = PushButton::new("Show Info")
317        .on_clicked(|| {
318            println!("[LOG] Info dialog shown");
319            dialog::information(None, "Info", "This is an information dialog");
320        })
321        .parent(&window)
322        .build();
323    bottom_layout.add_widget(Box::new(info_btn));
324
325    let warn_btn = PushButton::new("Show Warning")
326        .on_clicked(|| {
327            println!("[LOG] Warning dialog shown");
328            dialog::warning(None, "Warning", "This is a warning dialog");
329        })
330        .parent(&window)
331        .build();
332    bottom_layout.add_widget(Box::new(warn_btn));
333
334    let ask_btn = PushButton::new("Ask Question")
335        .on_clicked(|| {
336            println!("[LOG] Question dialog shown");
337            let answer = dialog::question(None, "Question", "Are you sure?");
338            println!("[LOG] Answer: {}", if answer { "Yes" } else { "No" });
339        })
340        .parent(&window)
341        .build();
342    bottom_layout.add_widget(Box::new(ask_btn));
343
344    let mut bottom_widget = Widget::new().parent(&window).build();
345    bottom_widget.set_hlayout(bottom_layout.layout_ptr());
346    main_layout.add_widget(Box::new(bottom_widget));
347
348    // ============================================================
349    // Status bar
350    // ============================================================
351    let status_label = Label::new("Status: Ready - All widgets loaded")
352        .parent(&window)
353        .build();
354    main_layout.add_widget(Box::new(status_label));
355
356    // ============================================================
357    // Show window and run
358    // ============================================================
359    window.show();
360    println!("[LOG] Application started - all widgets loaded");
361    println!("[LOG] Interact with widgets to see logs in terminal");
362
363    app.exec();
364}
Source

pub fn set_title(&self, title: &str)

Set the group box title at runtime.

Trait Implementations§

Source§

impl AsWidget for GroupBox

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 GroupBox

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§

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> ConnectExt for T
where T: AsWidget,

Source§

fn connect<S, T>( &self, _signal: S, target: &dyn AsWidget, _slot: T, conn_type: ConnType, ) -> bool
where S: SignalMeta, T: SlotMeta, S::Args: EqSlotArgs<T::Args>,

Connect a signal to a slot with compile-time type checking. Read more
Source§

fn disconnect<S, T>(&self, _signal: S, target: &dyn AsWidget, _slot: T) -> bool
where S: SignalMeta, T: SlotMeta,

Disconnect a signal-slot connection. Read more
Source§

impl<A> EqSlotArgs<A> for A

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.