Russian Qt Forum

Qt => Qt Quick => Тема начата: Dragonic от Март 30, 2015, 19:40



Название: Доступ к детям
Отправлено: Dragonic от Март 30, 2015, 19:40
Есть код, нужно получить доступ к rect1:
Код
Javascript
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.3
 
Item {
   width: 640
   height: 480
 
   property alias tabView1: tabView1
   property alias tabViewStyle1: tabView1.tabViewStyle1
 
   property alias rect1: tabView1.tabViewStyle1.rect1 // Invalid alias location
   property alias rect1: rect1 // Invalid alias reference. Unable to find id "rect1"
 
   TabView
   {
       id: tabView1
       anchors.fill: parent
       tabPosition: 1
       tabsVisible: true
       frameVisible: true
       Layout.minimumWidth: 100
       Layout.fillWidth: true
 
       property TabViewStyle tabViewStyle1: tabViewStyle1
 
       style: TabViewStyle {
           property Rectangle rect1: rect1
           id: tabViewStyle1
           frameOverlap: 1
           tab: Rectangle {
               id: rect1
               color: styleData.selected ? "steelblue" :"lightsteelblue"
               border.color:  "steelblue"
               implicitWidth: Math.max(text.width + 4, 80)
               implicitHeight: 20
               radius: 3
               Text {
                   id: text
                   anchors.centerIn: parent
                   text: styleData.title
                   color: styleData.selected ? "white" : "black"
               }
           }
           frame: Rectangle { color: "steelblue" }
           tabsMovable: true
       }
   }
}
 
Попытка доступа не достигает успеха: Invalid alias reference. Unable to find id "rect1"
Если немного поиздеваться над property внутри объектов, оно решает, что "Invalid alias location"
Собственно, Такая проблема может возникнуть в разных ситуациях, как её решать (без изменения текущей структуры кода)?


Название: Re: Доступ к детям
Отправлено: kibsoft от Март 30, 2015, 22:38
Проблема в том, что rect1 в данном случае не объект, а компонент (свойство tab принимает Component).
Простым способом сделать алиас здесь не удастся.
Если очень нужно, то можно извратиться, посмотреть код TabView и через свойство children по иерархии получить нужный объект. И то, я не уверен что получится.

UPD: у TabView есть "приватное" свойство __styleItem, можно попробовать через него. В любом случае, без просмотра кода TabView не обойтись.
Код TabView здесь (https://qt.gitorious.org/qt/qtquickcontrols/source/60026a8cc35dc1e806bcf61a137e236caa0878ed:src/controls/TabView.qml#L245).


Название: Re: Доступ к детям
Отправлено: Dragonic от Март 31, 2015, 00:22
Цитировать
Если очень нужно, то можно извратиться
Ладно rect1. Не могу понять, как сменить хотя бы tabViewStyle1.tabsMovable


Название: Re: Доступ к детям
Отправлено: kibsoft от Март 31, 2015, 15:17
Не могу понять, как сменить хотя бы tabViewStyle1.tabsMovable

Если надо динамически, то просто менять TabViewStyle каждый раз, когда нужно. Так будет правильней.
Ну или через свойство __styleItem попробовать на крайняк.


Название: Re: Доступ к детям
Отправлено: Отражение луны от Март 31, 2015, 21:15
Могу только сказать, что по коду абсолютно неясно чего Вы пытаетесь добиться. Опишите подробнее, уверен, решим любую задачу.
Alias не может ссылаться на компонент, т.к. это не объект, а значит данных в нем реально никаких нет. Собственно, зачем тут alias, если банальный property binding? Выглядит это следующим образом:
Код:
Item {
    id: root
    width: 640
    height: 480
    property bool tabsMovable: true
Код:
tabsMovable: root.tabsMovable
Иначе говоря, не нужно пытаться добраться до детей из объекта уровнем выше, правильным является обратный подход - дети сами должны читать данные объектов, находящихся уровнем выше.
Жду уточнений по поводу rect-а.


Название: Re: Доступ к детям
Отправлено: Dragonic от Апрель 01, 2015, 01:38
Если надо динамически, то просто менять TabViewStyle каждый раз, когда нужно. Так будет правильней.
Первое, что попытался. Как получить styleData.* извне - так и не понял.

Код:
tabsMovable: root.tabsMovable
Спасибо, заработало :) И с rect1 тоже (нужны изменения стиля на лету).

Актуален вопрос со styleData. Прикол в том, что Qt Creator вообще не в курсах, что такое бывает


Название: Re: Доступ к детям
Отправлено: Отражение луны от Апрель 01, 2015, 03:29
Creator может не видеть его, т.к. у него нет информации о конечной структуре объектов, но при этом такое обращение вполне может работать. Вопрос лишь в том, что я что-то не вижу у tabview такого свойства как style: http://doc.qt.io/qt-5/qml-qtquick-controls-tabview-members.html . Откуда такой код?)


Название: Re: Доступ к детям
Отправлено: Dragonic от Апрель 01, 2015, 05:27
Вопрос лишь в том, что я что-то не вижу у tabview такого свойства как style: http://doc.qt.io/qt-5/qml-qtquick-controls-tabview-members.html . Откуда такой код?)
http://doc.qt.io/qt-5/qml-qtquick-controls-styles-tabviewstyle.html


Название: Re: Доступ к детям
Отправлено: Отражение луны от Апрель 01, 2015, 13:56
Видимо, не допилили доки.

Опять таки, я вообще не понял, зачем Вам иметь доступ к styleData извне. В первую очередь надо сказать, что это набор объектов, для каждой вкладки тут существует свой styleData, для каждого из которых определен свой selected, и свой title. Доступ к ним и так есть через апи самого TableView (currentIndex) и Tab (title), и эти значения дожны меняться соотвествующим образом.
Если вы хотите менять стиль таблицы на лету извне, Вам надо:
Код:
Item {
id: root

property QtObject styleComponent: null
}
Код:
style: root.styleComponent
И в завершение - скажем, этот файл у Вас называется StyledTable, который используется в неком main.qml Изменение стиля извне будет выглядеть таким образом:
Код:
Item {
Component {
id: tableStyle1
TabViewStyle {
            property Rectangle rect1: rect1
            id: tabViewStyle1
            frameOverlap: 1
            tab: Rectangle {
                id: rect1
                color: styleData.selected ? "steelblue" :"lightsteelblue"
                border.color:  "steelblue"
                implicitWidth: Math.max(text.width + 4, 80)
                implicitHeight: 20
                radius: 3
                Text {
                    id: text
                    anchors.centerIn: parent
                    text: styleData.title
                    color: styleData.selected ? "white" : "black"
                }
            }
            frame: Rectangle { color: "steelblue" }
            tabsMovable: true
        }
}
StyledTable {
styleComponent: tableStyle1
}
}
Да, в таком компоненте styleData.selected будет работать, потому что создастся объект уже внутри TabView не смотря на то, что физически он объявлен в совершенно другом месте (к слову, может быть объявлен в любом, надо просто передать ссылку).
Вы можете также объявить список стилей внутри самой таблицы (или снаружи) и менять ссылку styleComponent на нужный вам компонент Но то, что в TabView корректно реализована смена стиля "на лету" я не гарантирую )