How to create component to be included into Column of SilicaFlickable

Hi,

for a configuration dialog (which supports country specific configurations i would
like to create contry sepecif configuration components that can be displayed
depending on the selected country - since the country specific configuration can be
quite different. Originally (before the externalization) the code looked like this:

Settings.qml

Page {
  SilicaFlickable {
     Column {
         PageHeader {}
         SectionHeader {}

         ComboBox {} // to select country
 
         // next 3 Elements shall be moved to a separate component
         // they depend on selected country in the ComboBox above
        ComboBox {}  
        ListModel {}
        ComboBox {}
        // end

        ComboBox {}
      }
   }
}

After externalizing the SettingsGermany component the settings page
is supposed to like like this - the specific configuration for germany is now
contained in a new encapsulated component SettingsGermany

Settings.qml - with using externalized components

Settings.qml
Page {
  SilicaFlickable {
     Column {
         PageHeader {}
         SectionHeader {}

         ComboBox {} // to select country

         // the 3 elements are now inserted as new component
         SettingsGermany{}

         ComboBox {}
      }
   }
}

The three Element for the configuration are now in a new Component which
is included in the settings page.

SettingsGermany.qml

Item {
   ComboBox {}  
   ListModel {}
   ComboBox {} 
}

The problem now is that the Page is not rendered properly the two combo boxes and the list model are not properly added to the Column in the SilicaFlickable where they are inteneded to be displayed. they are all displayed at the very top of the page above one another.

How can i externalize the 3 Elements to a new component (seprate file) - and include to a Column within a SilicaFlickable so that the elements of the component are rendered properly?

Or is there a better way to externalize and include country specific configuration?

Thanks in advance.

You have to wrap the elements in SettingsGermany.qml in their own Column or manage their layout manually. The component also needs a size, otherwise it won’t be picked up by the Column.

I’d also recommend using a Loader to load the correct Settings<Country>.qml component. (You can spend a lot of time to make the switching transition smooth with animated heights, opacity, etc.)

// Settings.qml
// ...
Column {
    // ...
    Loader { // will be resized to its contents
        source: ... // <selected settings component>
        opacity: status === Loader.Ready ? 1.0 : 0.0
        Behavior on opacity { FadeAnimator { } }
    }
    // ...
}

.

// Settings<Country>.qml
Column {
    width: parent.width // maybe: -2*Theme.horizontalPageMargin
    height: childrenRect.height
    // ...
}
1 Like

Thanks for the hint. The loader works fine. However the components that are loaded via the load are still not properly positioned. They are still in the upper left corner (as before). Is there anything that i missed?
The country specific components have a width and height assigned. However the referenced parent cannot really be resolved:

[W] unknown:7 - file:///tmp/qml-live-overlay--harbour-pollenflug-harbour-pollenflugSlrHRt/qml/components/SettingsFrance.qml:7: TypeError: Cannot read property 'width' of null
[W] unknown:10 - file:///tmp/qml-live-overlay--harbour-pollenflug-harbour-pollenflugSlrHRt/qml/components/SettingsGermany.qml:10: TypeError: Cannot read property 'width' of null

The UI now looks like this: The Departement Combobox should be below the country…

component_in_flickable

You can find the sources here:

and here

Change

width: parent.width

to

width: settingsPage.width

In the SettingsFrance and SettingsGermany

I think it would be better to define the column - or the component - width in the Settings-page, not in the component file. Otherwise the component can’t be used in other pages. And I assume parent.width can then be used.

Of course, that was just a quick splatter to see if it worked or not for the OP.

That would be better i guess, since tho component should not know the settings page. However how can i do that? Without the Loader this is quite easy, however when i want to stay/stick with the Loader how can i set the width for the loaded component?

i think i found the solution - setting the witdth to the Loader component worked.