Частично перекрывающиеся виджеты в макете Qt

Я пытаюсь частично перекрыть виджеты в макете Qt. Мой текущий макет выглядит следующим образом: он достигается с помощью QVBoxLayout, содержащего четыре QHBoxLayout дочерние элементы:

Мой текущий макет, полученный с помощью QVBoxLayout, содержащего четыре дочерних элемента QHBoxLayout

Я пытаюсь перегруппировать карты одной масти, чтобы добиться чего-то подобного (обратите внимание, что есть горизонтальное и вертикальное перекрытие):

Это то перекрытие, которого я пытаюсь добиться

К сожалению, вся документация по Qt и все сообщения о переполнении стека, которые я читал, пытаются избегать перекрытия виджетов, а не искать их. Может быть, есть способ установить отрицательное расстояние между виджетами или заставить макет рассчитывать максимальную ширину (например, в соответствии с количеством карт одной масти в этом случае)? Или мне нужно создать индивидуальный макет? Может быть, мне вообще не стоит использовать макеты?

Если это поможет, я добавляю виджеты в макеты с кодом, который выглядит так:

hLayout[card.getSuit()-1]->addWidget(cardWidget, 0, align);

person juef    schedule 14.05.2017    source источник


Ответы (1)


Вам нужно будет реализовать подкласс QLayout. В документации QT есть подробный пример решения именно вашей проблемы: Управление макетами

По сути, вам нужно будет определить следующее:

  • Структура данных для хранения элементов, обрабатываемых макетом. Каждый элемент является QLayoutItem.

  • addItem(), как добавлять элементы в макет.

  • setGeometry(), как выполнить компоновку.

  • sizeHint(), предпочтительный размер макета.

  • itemAt(), как перебирать макет.

  • takeAt(), как удалить элементы из макета.

В большинстве случаев вы также реализуете MinimumSize().

Ниже я скопировал наиболее важную часть кода из примера для вашего удобства:

class CardLayout : public QLayout
{
public:
    CardLayout(QWidget *parent, int dist): QLayout(parent, 0, dist) {}
    CardLayout(QLayout *parent, int dist): QLayout(parent, dist) {}
    CardLayout(int dist): QLayout(dist) {}
    ~CardLayout();

    void addItem(QLayoutItem *item);
    QSize sizeHint() const;
    QSize minimumSize() const;
    int count() const;
    QLayoutItem *itemAt(int) const;
    QLayoutItem *takeAt(int);
    void setGeometry(const QRect &rect);

private:
    QList<QLayoutItem*> list;
};


void CardLayout::setGeometry(const QRect &r)
{
    QLayout::setGeometry(r);

    if (list.size() == 0)
        return;

    int w = r.width() - (list.count() - 1) * spacing();
    int h = r.height() - (list.count() - 1) * spacing();
    int i = 0;
    while (i < list.size()) {
        QLayoutItem *o = list.at(i);
        QRect geom(r.x() + i * spacing(), r.y() + i * spacing(), w, h);
        o->setGeometry(geom);
        ++i;
    }
}
person J Storch    schedule 14.05.2017
comment
Не могу поверить, что я этого не видел. Спасибо за ссылку и добавленные детали! - person juef; 15.05.2017
comment
Эти конструкторы не компилируются - person Gerard097; 11.02.2019