Как сделать так, чтобы элементы QML увеличивались в соответствии с содержимым?

#qt #qml

#qt #qml

Вопрос:

Как заставить ServerItem увеличиваться в соответствии с содержимым? Прямо сейчас серверные элементы просто перекрывают друг друга.

main.qml

 import Qt 4.7
import "Teeworlds" as Teeworlds

Item {
    Column {
        Teeworlds.ServerItem {
            serverName: "InstaGib, lost [xyz]"
        }

        Teeworlds.ServerItem {
            serverName: "Arena.sbor (rus)"
        }
    }
}
  

ServerItem.qml

 import QtQuick 1.0

BorderImage {
    id: serverItem

    property string serverName: "unnamed server"
    property string gameType: "DM"
    property int numPlayers: 0
    property int maxPlayers: 8
    property int ping: 60

    Text {
        id: title
        text: parent.serverName
    }

    Grid {
        id: grid
        anchors.top: title.bottom
        columns: 2
        rows: 3
        Text { text: "Gametype: " }  Text { text: gameType }
        Text { text: "Players: " }   Text { text: numPlayers   "/"   maxPlayers }
        Text { text: "Ping: " }      Text { text: ping }
    }
}
  

Комментарии:

1. Примечание для себя на будущее: используйте ColumnLayout с Layout.fillHeight для динамического вычисления размера элемента столбца.

Ответ №1:

Вы должны задать размер контейнерам и добавить якоря / привязки в дочерних элементах :

main.qml :

 import QtQuick 1.1
import "Teeworlds" as Teeworlds

Item {
    width: 800; // root item so give a size
    height: 600;

    Flickable {
         clip: true;
         anchors.fill: parent; // use a flickable to allow scrolling
         contentWidth: width; // flickable content width is its own width, scroll only vertically
         contentHeight: layout.height; // content height is the height of the layout of items

         Column {
             id: layout;
             anchors { // the column should have a real size so make it fill the parent horizontally
                 left: parent.left;
                 right: parent.right;
             }

             Teeworlds.ServerItem {
                serverName: "InstaGib, lost [xyz]";
             }
             Teeworlds.ServerItem {
                serverName: "Arena.sbor (rus)";
             }
        }
    }
 }
  

Teeworlds /ServerItem.qml :

 import QtQuick 1.1

BorderImage {
    id: serverItem;
    height: grid.y   grid.height; // compute the item height using content position and size
    anchors { // to have a real size, items should grow horizontally in their parent
        left: parent.left;
        right: parent.right;
    }

    property string serverName  : "unnamed server";
    property string gameType    : "DM";
    property int      numPlayers  : 0;
    property int      maxPlayers   : 8;
    property int      ping               : 60;

    Text {
        id: title;
        text: parent.serverName;
    }
    Grid {
        id: grid;
        columns: 2;
        anchors { // the grid must anchor under the title but horizontally in the parent too
            top: title.bottom;
            left: parent.left;
            right: parent.right;
        }

        Text { text: "Gametype: " } 
        Text { text: gameType }
        Text { text: "Players: " }  
        Text { text: numPlayers   "/"   maxPlayers }
        Text { text: "Ping: " }    
        Text { text: ping }
    }
}
  

Помните, что по умолчанию все элементы, прямоугольники, изображения границ не имеют ни размера, ни позиции, и размер столбца, строки, потока, сетки, текста и изображения сами соответствуют своему содержимому, поэтому, если вы хотите использовать столбец для изменения размера его дочерних элементов, вы должны убедиться, что размер столбца больше не определяется автоматически одним из его дочерних элементов. Потому что в другом месте дочерние элементы останутся 0x0, а столбец также будет 0x0. Столбец должен быть привязан к своему родительскому элементу, чтобы иметь реальный размер, а его дочерние элементы должны быть привязаны горизонтально (слева и справа) к столбцу, чтобы иметь реальную ширину, а для элементов height размер должен соответствовать их внутреннему расположению…

Ответ №2:

На самом деле это довольно просто. Объекты ServerItem не имеют размера, вы можете видеть только содержимое, потому что нет обрезки. Решением было бы либо задать высоту и ширину в классе ServerItem (или экземплярах в main.qml), либо использовать растущий элемент, например столбец, в качестве корневого элемента ServerItem.

 import QtQuick 1.0

Column {
    id: serverItem

    BorderImage {
        anchors.fill: parent
    }

    //... the rest
}
  

Комментарии:

1. В документах, похоже, говорится, что привязки к столбцам запрещены: Note that the positioner assumes that the x and y positions of its children will not change. If you manually change the x or y properties in script, bind the x or y properties, use anchors on a child of a positioner, or have the height of a child depend on the position of a child, then the positioner may exhibit strange behavior. If you need to perform any of these actions, consider positioning the items without the use of a Column. Или я неправильно их читаю..

Ответ №3:

Вы должны явно задать размер, чтобы два элемента QML внутри строки / столбца не перекрывались.

Комментарии:

1. Я думаю, что на этот вопрос мой ответ правильный. Как заставить ServerItem увеличиваться в соответствии с содержимым? Прямо сейчас серверные элементы просто перекрывают друг друга.