控制连接到QToolButton的弹出QWidget

控制连接到QToolButton的弹出QWidget,qt,qt5,qwidget,Qt,Qt5,Qwidget,我想在点击QToolbutton时显示一个弹出窗口小部件 这可以通过向按钮本身添加操作来完成。 弹出窗口将包含三个按钮(更新、创建和取消)和一个文本输入字段 我有一些示例代码,其中只有一个按钮是我作为一个用户共享的 守则中最相关的部分是: auto button = new QToolButton(this); button->setText(" AA "); auto popup = new Popup(button, this); auto popup

我想在点击QToolbutton时显示一个弹出窗口小部件

这可以通过向按钮本身添加操作来完成。 弹出窗口将包含三个按钮(更新、创建和取消)和一个文本输入字段

我有一些示例代码,其中只有一个按钮是我作为一个用户共享的

守则中最相关的部分是:

    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()
函数,但它只清除弹出窗口的内容,而不关闭它

我可以用按钮触发信号,然后关闭弹出窗口吗

我同时问这两个问题,因为它们看起来非常相似:两次都是内容而不是弹出窗口受到影响。

  • 使用布局时,其边距会阻止对齐

  • 弹出窗口的QMenu可以通过亲属关系访问,但必须在按下按钮时访问,因为这是在首次显示时创建的

popup.h

\ifndef弹出窗口
#定义弹出窗口
#包括
类QToolButton;
类弹出窗口:公共QWidget
{
Q_对象
公众:
显式弹出窗口(QWidget*parent=nullptr);
Q_信号:
无效点击();
};
#恩迪夫
弹出.cpp

#包括“popup.h”
#包括
#包括
#包括
Popup::Popup(QWidget*父项)
:QWidget(父项)
{
自动布局=新的QVBoxLayout(此);
布局->设置内容边缘(0,0,0,0);
布局->添加拉伸();
自动更新按钮=新的QPushButton(“更新”);
布局->添加小部件(更新按钮);
连接(updateButton、&QPushButton::clicked、this、&Popup::clicked);
}
main window.h


MainWindow::MainWindow()
{
自动小部件=新的QWidget;
setCentralWidget(小部件);
自动布局=新的QHBoxLayout(小部件);
布局->添加拉伸();
自动按钮=新建QToolButton;
按钮->设置文本(“AA”);
布局->添加小部件(按钮);
自动弹出=新弹出;
auto popupAction=新的QWidgetAction(此);
popupAction->setDefaultWidget(弹出窗口);
按钮->设置PopupMode(QToolButton::InstantPopup);
按钮->添加操作(弹出操作);
连接(弹出,&弹出::单击,[弹出](){
if(QWidget*p=popup->parentWidget())
p->close();
});
}
您的弹出窗口小部件不是实际的弹出窗口,而是真实弹出窗口中的一个小部件。 因此,您移动的是真正弹出窗口中的小部件,而不是弹出窗口本身

您链接到的问题中的解决方案使用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);

将弹出类更改为扩展/继承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);

谢谢你的提示。我曾尝试在
QMenu
中转换我的
QWidget
,但它只适用于示例,而不适用于真实的情况:在我的真实代码中,我需要在小部件内部放置一个网格布局,这对于
QMenu
是不可能的。使用qgridlayout更新了示例答案。好的,谢谢。我现在会选择eyllanesc解决方案(已经开始实施),但我相信其他人会欣赏您的布局解决方案。如果有时间,我会将这两个解决方案作为分支添加到Github存储库中。我以前尝试访问父级,但失败。也许,看到您发布的消息,我对它更加信任,事实上,使用
parentWidget()
既可以移动小部件(从内部
showEvent()
),也可以关闭它(在我的
doUpdate()
槽中,当按钮被点击时触发)。谢谢@a、 我已经为你的回购创建了一个PR,这样你可以快速测试它。
button->setPopupMode(QToolButton::InstantPopup);
auto menu = new Popup(button, this);
auto action = new QAction("Test");
menu->addAction(action);
button->setMenu(menu);
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);