QPushButton 在第二个布局中不可点击

QPushButton not clickable in second Layout

已经有人问过类似的问题,但那个人正在使用 PyQt5 和 Designer,所以我找不到答案,因为我是“从头开始”用 C++ 编码的。

我是 Qt 的初学者,我正在尝试将两个 QPushButton 添加到特定布局中的 window。 起初,我试图将它们添加到 window 到已经存在的 QVBoxLayout 中,如下所示(this 是 window 和 textBrowser 是一个QTextBrowser。按钮已经正确初始化了)。

在这种情况下按钮工作得很好:

auto content = new QWidget(this);
auto windowLayout = new QVBoxLayout(content);
windowLayout->addWidget(textBrowser);

windowLayout->addWidget(button1, 0, Qt::AlignLeft);
windowLayout->addWidget(button2, 0, Qt::AlignRight);

setCentralWidget(content);

但是,按钮是垂直堆叠的。我希望它们彼此水平相邻,所以我尝试将按钮添加到 QHBoxLayout,然后将其添加到现有的 QVBoxLayout:

auto content = new QWidget(this);
auto windowLayout = new QVBoxLayout(content);
windowLayout->addWidget(textBrowser);

auto buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(button1, 0, Qt::AlignRight);
buttonLayout->addWidget(button2, 0, Qt::AlignLeft);

windowLayout->addItem(buttonLayout);

setCentralWidget(content);

这些按钮出现在我希望它们出现的位置,但不幸的是,即使它们没有被禁用,它们也无法再点击。

为什么会这样?我的理论是布局可能会覆盖按钮,所以我尝试先将 QHBoxLayout 添加到 QVBoxLayout,然后再添加按钮,但没有任何改变。

非常感谢任何帮助或信息。

摘自 QLayout::addItem() documentation:

The function addItem() is not usually called in application code. To add a widget to a layout, use the addWidget() function; to add a child layout, use the addLayout() function provided by the relevant QLayout subclass.

因此,将 addItem() 替换为 addLayout() 将解决您的问题。

要回答为什么 addItem() 有那个效果,你可以看看 Qt's source code:

void QBoxLayout::addLayout(QLayout *layout, int stretch)
{
    insertLayout(-1, layout, stretch);
}

void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch)
{
    Q_D(QBoxLayout);
    if (!d->checkLayout(layout))
        return;
    if (!adoptLayout(layout))
        return;
    if (index < 0)                                // append
        index = d->list.count();
    QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch);
    d->list.insert(index, it);
    invalidate();
}

void QBoxLayout::addItem(QLayoutItem *item)
{
    Q_D(QBoxLayout);
    QBoxLayoutItem *it = new QBoxLayoutItem(item);
    d->list.append(it);
    invalidate();
}

addItem() 相比,addLayout() 调用 adoptLayout(),它重新设置要添加的布局中的小部件。这让父布局控制小部件的大小并确定应该定向到小部件的事件(鼠标悬停事件、鼠标按下事件等)