问题
I am trying to make widgets overlap partly in a Qt layout. My current layout is the following, achieved with a QVBoxLayout containing four QHBoxLayout children:
I'm trying to regroup cards of the same suit, in order to achieve something like this (note that there is horizontal and vertical overlapping):
Unfortunately, all the Qt documentation and all the Stack Overflow posts I have read try to avoid widgets overlapping rather than to seek it. Maybe there's a way to set negative spacing between widgets, or forcing a layout to have a maximum width calculated (e.g. according to the number of cards of one suit in this case)? Or do I have to create a custom layout? Maybe I should not be using layouts at all?
If it's any help, I'm adding the widgets to the layouts with code that looks like this:
hLayout[card.getSuit()-1]->addWidget(cardWidget, 0, align);
回答1:
You will need to implement a subclass of QLayout. There is a detailed example in the QT documentation addressing exactly you problem: Layout Management
Basically, you will need to define the following:
A data structure to store the items handled by the layout. Each item is a QLayoutItem.
addItem(), how to add items to the layout.
setGeometry(), how to perform the layout.
sizeHint(), the preferred size of the layout.
itemAt(), how to iterate over the layout.
takeAt(), how to remove items from the layout.
In most cases, you will also implement minimumSize().
Below I have copied the most important part of the code in the example, for your convenience:
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;
}
}
来源:https://stackoverflow.com/questions/43968622/making-widgets-partly-overlap-in-a-qt-layout