Iced button not displaying text

Hi,

I'm using Iced for an application and having trouble getting text to show on Buttons

mod capture;

use capture::{capture_screenshot, screenshot_to_iced_image};
use iced::widget::container::Appearance;
use iced::widget::image::viewer;
use iced::widget::image::Handle;
use iced::widget::{
    button, column, container, row, text, Button, Column, Container, Image, Row, Text,
};
use iced::window::Position::Specific;
use iced::{window, Alignment, Application, Command, Element, Length, Sandbox, Settings};
use std::rc::Rc;

pub fn main() -> iced::Result {
    let (width, height, raw_pixels_u32) = capture_screenshot().unwrap();
    let screenshot = screenshot_to_iced_image(width, height, raw_pixels_u32);

    let settings = Settings {
        id: Default::default(),
        window: window::Settings {
            size: (width as u32, height as u32),
            position: Specific(0, 0), // Default::default(),
            min_size: None,
            max_size: None,
            visible: true,
            resizable: true,
            decorations: false,
            transparent: false,
            always_on_top: false,
            icon: None,
            platform_specific: Default::default(),
        },
        flags: screenshot,
        antialiasing: Default::default(),
        exit_on_close_request: true,
        default_font: Default::default(),
        default_text_size: Default::default(),
        text_multithreading: Default::default(),
        try_opengles_first: Default::default(),
    };

    Counter::run(settings)
}

struct Counter {
    value: i32,
    screenshot: Handle,
}

#[derive(Debug, Clone, Copy)]
enum Message {
    IncrementPressed,
    DecrementPressed,
}

impl Counter {
    fn new_with_screenshot(screenshot: Handle) -> Self {
        Self {
            value: 0,
            screenshot,
        }
    }
}

impl Application for Counter {
    type Executor = iced::executor::Default;
    type Message = Message;
    type Theme = iced::Theme;
    type Flags = Handle;

    fn new(flags: Self::Flags) -> (Self, Command<Message>) {
        (
            Self {
                value: 0,
                screenshot: flags,
            },
            Command::none(),
        )
    }

    fn title(&self) -> String {
        String::from("Counter - Iced")
    }

    fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
        match message {
            Message::IncrementPressed => {
                self.value += 1;
            }
            Message::DecrementPressed => {
                self.value -= 1;
            }
        }
        Command::none()
    }

    fn view(&self) -> Element<Message> {
        // let viewer = viewer(self.screenshot.clone())
        //     .width(Length::Fill)
        //     .height(Length::Fill);

        // let inc_button = Button::new("Incremenet").width(Length::Fixed(20 as f32)).height(Length::Fixed(20 as f32));
        // let button = button("Click me to increment")
        //     .on_press(Message::IncrementPressed);

        column![
            button("Increment").on_press(Message::IncrementPressed),
            text("Test").size(50),
            //viewer,
            row![
                button("Increment")
                    .on_press(Message::IncrementPressed)
                    .width(Length::Fixed(80 as f32))
                    .height(Length::Fixed(30 as f32)),
                // inc_button
            ]
        ]
        .padding(20)
        // .width(Length::Fill)
        // .height(Length::Fill)
        .align_items(Alignment::Center)
        .into()
    }
}

Regardless of how I initialize the button it looks like this

button("Increment").on_press(Message::IncrementPressed),
            text("Test").size(50),
            //viewer,
            row![
                button("Increment")
                    .on_press(Message::IncrementPressed)
                    .width(Length::Fixed(80 as f32))
                    .height(Length::Fixed(30 as f32)),
                // inc_button
            ]

image

Any idea what I could be doing wrong here?

Thanks!

image

It works fine on my machine once I changed a few things so that it would compile.

I'd try following the troubleshoot section in Iced readme

By the way, you can initialize remaining fields with default parameters thus:

  let settings = Settings {
      window: window::Settings {
          -snip-
      },
      exit_on_close_request: true,
      ..Settings::default()
  };

Weird...any chance you could provide me with your main.rs file?

Also is that with iced == "0.9.0"?

Trying to use ..Settings::default()

 let settings = Settings {
        id: Default::default(),
        window: window::Settings {
            size: (width as u32, height as u32),
            position: Specific(0, 0), // Default::default(),
            min_size: None,
            max_size: None,
            visible: true,
            resizable: true,
            decorations: false,
            transparent: false,
            always_on_top: false,
            icon: None,
        },
        flags: screenshot,
        exit_on_close_request: true,
        ..Settings::default()
    };

Gives me a compile error

the trait bound iced::widget::image::Handle: std::default::Default is not satisfied
the trait std::default::Default is implemented for iced::Settings<Flags>
required for iced::Settings<iced::widget::image::Handle> to implement std::default::DefaultrustcClick for full compiler diagnostic

I think because I've got it setup to take in a iced::widget::image::Handle

impl Application for Counter {
    type Executor = iced::executor::Default;
    type Message = Message;
    type Theme = iced::Theme;
    type Flags = Handle;

    // here
    fn new(flags: Self::Flags) -> (Self, Command<Message>) {
        (
            Self {
                value: 0,
                screenshot: flags,
            },
            Command::none(),
        )
    }

& fwiw I tried running with

cargo run --features iced/glow

But it did not have any effect

image

Small breakthrough -

If I use Settings::default() instead of creating my settings and passing them through, the text appears, I'm just not sure why.

pub fn main() -> iced::Result {
    let (width, height, raw_pixels_u32) = capture_screenshot().unwrap();
    let screenshot = screenshot_to_iced_image(width, height, raw_pixels_u32);

    //     let settings = Settings {
    //       window: window::Settings {
    //           -snip-
    //       },
    //       exit_on_close_request: true,
    //       ..Settings::default()
    //   };
    let settings = Settings {
        id: Default::default(),
        window: window::Settings {
            size: (width as u32, height as u32),
            position: Specific(0, 0), // Default::default(),
            min_size: None,
            max_size: None,
            visible: true,
            resizable: true,
            decorations: true,
            transparent: false,
            always_on_top: false,
            icon: None,
            platform_specific: Default::default(),
        },
        flags: Default::default(),
        exit_on_close_request: true,
        default_font: Default::default(),
        default_text_size: Default::default(),
        text_multithreading: Default::default(),
        antialiasing: Default::default(),
        try_opengles_first: Default::default(),
        // ..Settings::default()
    };

    let default_settings: Settings<()> = Settings::default();
    Counter::run(settings) // Does not work!
    // Counter::run(Settings::default()) // Works!

It works if your Flags type is not Handle. For example, change it to Option<Handle> and wrap the screenshot in Some().

I don't know why it behaves that way. There is no indication in the code or docs for it. At least not that I could find.

Ugh....found it, the culprit was default_text_size

I guess setting it like default_text_size = Default::default(),

caused it to be set to 0 instead of the true default (20)

let settings = Settings {
        id: Default::default(),
        window: window::Settings {
            size: (width as u32, height as u32),
            position: Specific(0, 0), // Default::default(),
            min_size: None,
            max_size: None,
            visible: true,
            resizable: true,
            decorations: true,
            transparent: false,
            always_on_top: false,
            icon: None,
            platform_specific: Default::default(),
        },
        flags: screenshot,
        exit_on_close_request: true,
        default_font: Default::default(),
        default_text_size: 20.0, // Default::default(),
        text_multithreading: Default::default(),
        antialiasing: Default::default(),
        try_opengles_first: Default::default(),
        // ..Settings::default()
    };
1 Like

Oh, yes, that's it! Handle does not implement Default, so you are required to specify every field of the struct. Option<Handle> does implement Default, allowing ..Settings::default() to be used.

The default value for f32 is 0.0. :joy:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.