34

How to make ServerItem to grow to fit contents? Right now ServerItems just overlap each other.

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 }
    }
}
lamefun
  • 3,862
  • 4
  • 20
  • 22
  • 2
    Note to future self: use [ColumnLayout](http://doc.qt.io/qt-5/qml-qtquick-layouts-columnlayout.html) with `Layout.fillHeight` for dynamic calculation of column item size. – Adversus Apr 20 '15 at 13:18

3 Answers3

17

You must give a size to containers, and add anchors / bindings in children :

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 }
    }
}

Remember that by default all Item, Rectangle, BorderImage have no size,no position, and that Column, Row, Flow, Grid, Text and Image size themself to their content, so if you want to use the Column to resize its children you must ensure that column size is no more automatically defined by the one of its children. Because elsewhere, the children will stay 0x0 and column will also be 0x0. Column should be anchored into its parent to have a real size, and its children should anchor horizontally (left and right) into column to have a real width, and for the height items must size them self according to their internal layout...

TheBootroo
  • 7,408
  • 2
  • 31
  • 43
11

Actually that's quite easy. The ServerItem objects have no size, you can only see the content because there is no clipping. The solution would be either to set height and width in the ServerItem class (or the instances in main.qml) or to use a growing element, e.g. a Column, as the ServerItem root element.

import QtQuick 1.0

Column {
    id: serverItem

    BorderImage {
        anchors.fill: parent
    }

    //... the rest
}
blakharaz
  • 2,580
  • 13
  • 18
  • 4
    The docs seem to say, that anchors are prohibited with columns: `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.` Or am I reading them wrong.. – mlvljr Jun 29 '12 at 21:29
1

You have to set a size explicitly so that two QML elements inside a Row/Column doesn't overlap.

RajaRaviVarma
  • 2,502
  • 25
  • 26
  • I think for this question, my answer is correct. **How to make ServerItem to grow to fit contents? Right now ServerItems just overlap each other.** – RajaRaviVarma Mar 20 '15 at 03:54