2014-12-29 3 views
2

У меня есть ListView, который отображает некоторые данные из API. В моем элементе списка мне нужно иметь два разных дерева компонентов в зависимости от данных для этой строки. Более конкретно, если строка имеет связанное изображение, мне нужно отобразить изображение с помощью метки, определенной определенным образом. Если у него нет изображения, я хочу отобразить только метку, устроенную по-другому. Для меня это звучит так, как будто я хочу создать два разных компонента и выбрать, какой компонент включать, динамически.Условно включать компонент на основе значения свойства

В настоящее время она выглядит примерно так, в сокращенном виде:

ListItem.Empty { 
    id: matchItem 
    property string team1Name 
    property string team2Name 
    property string team1Logo 
    property string team2Logo 

    width: parent.width 

    Item { 
     id: team1Info 
     width: parent.width*0.3 

     anchors { 
      left: parent.left 
      top: parent.top 
      bottom: parent.bottom 
     } 

     Item { 
      anchors.fill: parent 
      anchors.margins { 
       top: units.gu(2) 
       bottom: units.gu(2) 
      } 

      Image { 
       id: team1LogoImage 
       source: team1Logo 
       width: parent.width 
       height: units.gu(5) 
       fillMode: Image.PreserveAspectFit 
       anchors.horizontalAlignment: parent.horizontalCenter 
      } 

      Label { 
       text: team1Name 
       anchors.horizontalAlignment: Text.Center 
      } 
     } 
    } 

    // Some more elements and a repeat of the above for the second team 
} 

Вопрос заключается в том, что если team1Logo или team2Logo не является допустимым URL, например, если команда не имеет логотип, изображение компонент не удастся.

То, что я хотел бы сделать, это по существу:

if (team1Logo === "") { 
    Label { 
     // Stuff to make it look good without an image 
    } 
} else { 
    Image { 
     source: team1Logo 
    } 

    Label { 
     // Stuff 
    } 
} 

Но, насколько я знаю, что это не так, как работает QML.

Я рассмотрел компонент Loader, который, похоже, может соответствовать счету, поскольку я мог использовать условные обозначения при настройке свойства source на загрузчике, но я не мог заставить его работать. Кто-нибудь знает, как добиться того, что я описал?

+0

Нужно ли рассматривать только пустые логотипы или искаженные символы? В первом случае вы можете использовать условный оператор над 'logo1 ===" "' для загрузки внутри загрузчика одного из двух разных компонентов: одного для метки и одного для метки + изображения. В последнем случае, я думаю, вы можете использовать статус ошибки загрузки для искаженного URL [статус, обсуждаемый здесь] (http://doc.qt.io/qt-5/qml-qtquick-loader.html#status-prop) и снова загружать различные компоненты для конкретного случая. – BaCaRoZzo

+1

Что делать, если вы обнаружили, что у команды нет допустимого логотипа и вместо URL-адреса установлен пустой URL-адрес изображения?Вы могли бы даже указать на образ заполнителя, который иллюстрирует отсутствие логотипа, устраняя необходимость в условных пользовательских интерфейсах. – Mitch

+0

@BaCaRoZzo Я думаю, что я могу игнорировать случай некорректных URL-адресов на данный момент. Вы в основном описываете, что я пытался сделать, но я не мог заставить загрузчика фактически загружать компоненты. У вас есть пример, на который я мог бы смотреть? –

ответ

6

Оказалось довольно простым в реализации Loader. Пример:

Item { 
    id: team1Info 

    Loader { 
     id: team1ItemLoader 
     property string name: model.team1Name 
     property string logo: model.team1Logo 

     source: (logo) ? "TeamLogoItem.qml" : "TeamItem.qml" 
    } 
} 

В этом примере, name и logo затем становятся доступными внутри TeamLogoItem.qml или TeamItem.qml как свойства.

1

Ответ на @TommyBrunn работает только если TeamItem.qml не определяет property вы хотите передать в Это означает, что:.

  • Вы не можете использовать property alias в компоненте
  • Вы не можете поставить значение любого по умолчанию для такого свойства

в качестве альтернативы, вы можете использовать setSource() для Loader передать значение свойств для загруженного компонента:

// ### TeamItem.qml (and TeamLogoItem.qml, similarly) 
Label { 
    property alias name: text 
    property string logo: "qrc:/images/logos/dummy.png" 
}  
// ### main.qml 
Item { 
    id: team1Info 

    Loader { 
     Component.onCompleted: { 
      var qml = model.team1Logo ? "TeamLogoItem.qml" : "TeamItem.qml"; 
      setSource(qml, { name:model.team1Name, logo:model.team1Logo }) 
     } 
    } 
} 

Вы можете также выбрать, чтобы пройти различные значения свойств в-например. не передавайте логотип TeamItem.qml на основе QML, который вы загружаете. Они не должны иметь один и тот же интерфейс.

Смежные вопросы