控制附加到 QToolButton 的弹出式 QWidget
Controlling a popup QWidget attached to a QToolButton
我想要在单击 QTool 按钮时显示弹出窗口小部件。
这可以通过向按钮本身添加一个动作来完成。
弹出窗口将包含三个按钮(更新、创建和取消)和一个文本输入字段。
我有一些示例代码,其中只有一个按钮,我已将其共享为 Github repository。
代码中最相关的部分是:
auto button = new QToolButton(this);
button->setText(" AA ");
auto popup = new Popup(button, this);
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
结果如下:
我有两个问题无法解决:
- 使弹出窗口小部件与按钮右对齐。
- 单击其中一个按钮时关闭弹出窗口小部件。
右对齐弹出窗口
已经有一个类似的问题:。
我可以添加建议的代码:
void Popup::showEvent(QShowEvent*)
{
QPoint p = this->pos();
QRect geo = clickedButton->geometry();
this->move(p.x()+geo.width()-this->geometry().width(), p.y());
}
但只有弹出窗口的内容与按钮右对齐,而不是弹出窗口本身:
关闭弹出窗口
如果我单击弹出窗口中的任意位置(小部件除外),它就会关闭。我对这个很好。
但是如果我无法点击按钮关闭弹出窗口。
我试图调用 close()
函数,但它只清除弹出窗口的内容而不关闭它。
我可以让按钮触发信号然后关闭弹出窗口吗?
我同时问这两个问题,因为它们看起来非常相似:两次都是内容而不是弹出窗口受到影响。
当您使用布局时,它的边距会妨碍对齐。
Popup 的 QMenu 可以通过亲缘关系访问,但是必须在按下按钮时访问,因为它是在首次显示时创建的。
popup.h
#ifndef POPUP_H
#define POPUP_H
#include <QWidget>
class QToolButton;
class Popup : public QWidget
{
Q_OBJECT
public:
explicit Popup(QWidget* parent=nullptr);
Q_SIGNALS:
void clicked();
};
#endif
popup.cpp
#include "popup.h"
#include<QWidget>
#include<QVBoxLayout>
#include<QPushButton>
Popup::Popup(QWidget* parent)
: QWidget(parent)
{
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addStretch();
auto updateButton = new QPushButton("Update");
layout->addWidget(updateButton);
connect(updateButton, &QPushButton::clicked, this, &Popup::clicked);
}
mainwindow.h
MainWindow::MainWindow()
{
auto widget = new QWidget;
setCentralWidget(widget);
auto layout = new QHBoxLayout(widget);
layout->addStretch();
auto button = new QToolButton;
button->setText(" AA ");
layout->addWidget(button);
auto popup = new Popup;
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
connect(popup, &Popup::clicked, [popup](){
if(QWidget *p = popup->parentWidget())
p->close();
});
}
auto popup = new Popup(button, this);
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
您的 Popup 小部件不是实际的弹出窗口,而只是真正的弹出窗口中的一个小部件。
所以你要移动的是真正弹出窗口中的小部件,而不是弹出窗口本身。
您链接到的问题中的解决方案使用 QMenu,并且它适用于 QMenu。
在您的代码中替换
connect(button, &QToolButton::clicked, this, &MainWindow::showPopup);
auto updateButton = new QPushButton("Update");
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(updateButton);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
和
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
auto action = new QAction("Test");
menu->addAction(action);
button->setMenu(menu);
将 Popup class 更改为 extend/inherit QMenu,取消注释 showEvent 方法并从构造函数中删除所有内容。
编辑
您可以为 qmenu 设置布局并向其添加小部件。
auto menuLayout = new QGridLayout();
auto menuBtn1 = new QPushButton("Btn1");
auto menuBtn2 = new QPushButton("Btn2");
auto menuBtn3 = new QPushButton("Btn3");
menuLayout->addWidget(menuBtn1, 0, 0);
menuLayout->addWidget(menuBtn2, 0, 1);
menuLayout->addWidget(menuBtn3, 1, 0);
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
menu->setLayout(menuLayout);
我想要在单击 QTool 按钮时显示弹出窗口小部件。
这可以通过向按钮本身添加一个动作来完成。 弹出窗口将包含三个按钮(更新、创建和取消)和一个文本输入字段。
我有一些示例代码,其中只有一个按钮,我已将其共享为 Github repository。
代码中最相关的部分是:
auto button = new QToolButton(this);
button->setText(" AA ");
auto popup = new Popup(button, this);
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
结果如下:
我有两个问题无法解决:
- 使弹出窗口小部件与按钮右对齐。
- 单击其中一个按钮时关闭弹出窗口小部件。
右对齐弹出窗口
已经有一个类似的问题:
我可以添加建议的代码:
void Popup::showEvent(QShowEvent*)
{
QPoint p = this->pos();
QRect geo = clickedButton->geometry();
this->move(p.x()+geo.width()-this->geometry().width(), p.y());
}
但只有弹出窗口的内容与按钮右对齐,而不是弹出窗口本身:
关闭弹出窗口
如果我单击弹出窗口中的任意位置(小部件除外),它就会关闭。我对这个很好。
但是如果我无法点击按钮关闭弹出窗口。
我试图调用 close()
函数,但它只清除弹出窗口的内容而不关闭它。
我可以让按钮触发信号然后关闭弹出窗口吗?
我同时问这两个问题,因为它们看起来非常相似:两次都是内容而不是弹出窗口受到影响。
当您使用布局时,它的边距会妨碍对齐。
Popup 的 QMenu 可以通过亲缘关系访问,但是必须在按下按钮时访问,因为它是在首次显示时创建的。
popup.h
#ifndef POPUP_H
#define POPUP_H
#include <QWidget>
class QToolButton;
class Popup : public QWidget
{
Q_OBJECT
public:
explicit Popup(QWidget* parent=nullptr);
Q_SIGNALS:
void clicked();
};
#endif
popup.cpp
#include "popup.h"
#include<QWidget>
#include<QVBoxLayout>
#include<QPushButton>
Popup::Popup(QWidget* parent)
: QWidget(parent)
{
auto layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->addStretch();
auto updateButton = new QPushButton("Update");
layout->addWidget(updateButton);
connect(updateButton, &QPushButton::clicked, this, &Popup::clicked);
}
mainwindow.h
MainWindow::MainWindow()
{
auto widget = new QWidget;
setCentralWidget(widget);
auto layout = new QHBoxLayout(widget);
layout->addStretch();
auto button = new QToolButton;
button->setText(" AA ");
layout->addWidget(button);
auto popup = new Popup;
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
connect(popup, &Popup::clicked, [popup](){
if(QWidget *p = popup->parentWidget())
p->close();
});
}
auto popup = new Popup(button, this);
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(popup);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
您的 Popup 小部件不是实际的弹出窗口,而只是真正的弹出窗口中的一个小部件。 所以你要移动的是真正弹出窗口中的小部件,而不是弹出窗口本身。
您链接到的问题中的解决方案使用 QMenu,并且它适用于 QMenu。
在您的代码中替换
connect(button, &QToolButton::clicked, this, &MainWindow::showPopup);
auto updateButton = new QPushButton("Update");
auto popupAction = new QWidgetAction(this);
popupAction->setDefaultWidget(updateButton);
button->setPopupMode(QToolButton::InstantPopup);
button->addAction(popupAction);
和
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
auto action = new QAction("Test");
menu->addAction(action);
button->setMenu(menu);
将 Popup class 更改为 extend/inherit QMenu,取消注释 showEvent 方法并从构造函数中删除所有内容。
编辑
您可以为 qmenu 设置布局并向其添加小部件。
auto menuLayout = new QGridLayout();
auto menuBtn1 = new QPushButton("Btn1");
auto menuBtn2 = new QPushButton("Btn2");
auto menuBtn3 = new QPushButton("Btn3");
menuLayout->addWidget(menuBtn1, 0, 0);
menuLayout->addWidget(menuBtn2, 0, 1);
menuLayout->addWidget(menuBtn3, 1, 0);
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
menu->setLayout(menuLayout);