【问题标题】:Hide a QDockWidget's widget and set vertical title bar simultaneously隐藏 QDockWidget 的小部件并同时设置垂直标题栏
【发布时间】:2016-06-15 10:02:27
【问题描述】:

我在QDockWidget 中有一个简单的QWidget 和我自己的这个停靠小部件的标题栏。在这个标题栏中,我放了一个QPushButton,当它被触发时,我可以:

  • 设置标题栏垂直
  • 将小部件隐藏在QDockWidget

我设法让他们两个分别工作,但我无法成功同时

这是标题栏的代码:

QDockTitleBar::QDockTitleBar(const QString &title, QDockWidget * parent)
    : QWidget(parent)
{
    pDock = qobject_cast<QSuiteDockWidget*>(parentWidget());

    m_pMainLayout = new QHBoxLayout(this);

    m_pLabel = new QLabel(title, this);
    m_pMainLayout->addWidget(m_pLabel);

    m_pMainLayout->addStretch();

    m_pToggleButton = new QPushButton(this);
    //m_pToggleButton->setIcon(...); // whatever
    m_pToggleButton->setFlat(true);
    connect(m_pToggleButton, SIGNAL(clicked()), this, SLOT(toggleButtonTriggered()));
    m_pMainLayout->addWidget(m_pToggleButton);    
}

void QDockTitleBar::resizeEvent(QResizeEvent* event)
{
    if (pDock->features() & QDockWidget::DockWidgetVerticalTitleBar) 
        qDebug() << "I am Vertical";
    else 
        qDebug() << "I am Horizontal";
}

void QDockTitleBar::toggleButtonTriggered()
{
    const QDockWidget::DockWidgetFeatures features = pDock->features();

    if(features & QDockWidget::DockWidgetVerticalTitleBar)
    {
        pDock->widget()->show(); // comment this one...
        pDock->setFeatures(features ^ QDockWidget::DockWidgetVerticalTitleBar);
    }
    else
    {
        pDock->widget()->hide(); //... and this one : the title bar is set vertical
        pDock->setFeatures(features | QDockWidget::DockWidgetVerticalTitleBar);
    }           
}

在我的主要功能中:

QDockWidget* dock = new QDockWidget();
dock->setWindowTitle("DOCK");
QDockTitleBar* labelDock = new QDockTitleBar("DOCK", dock);
QWidget* widget = new QWidget(dock);
dock->setTitleBarWidget(labelDock);
dock->setWidget(widget);
addDockWidget(Qt::RightDockWidgetArea, dock);

NB : 如果我改变 pDock-&gt;widget()-&gt;hide() in pDock-&gt;widget()-&gt;show() 反之亦然,我几乎有想要的行为,但小部件在标题栏是水平的(我希望标题栏垂直时隐藏它)...

我也放了resizeEvent()。当我触发按钮时,标题栏水平,我有:

我是垂直的

我是水平的

我是水平的

如果我再次触发按钮:

我是垂直的

我是水平的

我是水平的

我是水平的

谁能解释我这种行为和/或告诉我我做错了什么以及如何解决它?


编辑:我在 Qt5.6 上工作,如果这很重要的话。

我不关注resizeEvent() 是否被调用,这只是不是想要的行为。目前:

1/ 如果我使用此代码:

if(features & QDockWidget::DockWidgetVerticalTitleBar)
    pDock->setFeatures(features ^ QDockWidget::DockWidgetVerticalTitleBar);
else
    pDock->setFeatures(features | QDockWidget::DockWidgetVerticalTitleBar);

它应该像它应该工作一样工作:当按钮被触发时,标题栏设置为垂直,当我再次触发按钮时返回到水平。此外,小部件始终显示。

2/ 如果我使用此代码:

if(features & QDockWidget::DockWidgetVerticalTitleBar)
{
    pDock->widget()->show();
    pDock->setFeatures(features ^ QDockWidget::DockWidgetVerticalTitleBar);
}
else
{
    pDock->widget()->hide();
    pDock->setFeatures(features | QDockWidget::DockWidgetVerticalTitleBar);
}   

然后,如果我触发按钮,小部件被隐藏(根据需要),但标题栏未设置垂直。如果我再次触发按钮,小部件显示(根据需要),并且标题栏仍然是水平的(看起来很正常,因为它在第一次触发时没有改变)。

3/ 如果我使用这段代码(这是我想要的行为似乎接近的地方):

if(features & QDockWidget::DockWidgetVerticalTitleBar)
{
    pDock->widget()->hide();
    pDock->setFeatures(features ^ QDockWidget::DockWidgetVerticalTitleBar);
}
else
{
    pDock->widget()->show();
    pDock->setFeatures(features | QDockWidget::DockWidgetVerticalTitleBar);
}  

然后:

  • 第一次触发:标题栏设置为垂直(没关系)但小部件仍然显示
  • 第二次触发:标题栏回到水平但这次隐藏的小部件
  • 第三次触发,之后是:标题栏垂直显示小部件,然后标题栏水平显示小部件。我想要相反的,即标题栏垂直/小部件隐藏标题栏水平/小部件显示。

【问题讨论】:

    标签: c++ qt qdockwidget


    【解决方案1】:

    首先,我尝试使用 qt4.86 和 qt5.5.1 编译您的示例。他们的行为有点不同。使用 qt4.86 我认为它工作正常。但是对于 qt5.5.1,它确实如您所描述的那样显示“我是水平的”。我不知道它们为什么不同,但确实如此。

    顺便说一句,当我从主窗口中删除 QDockWidget 时,它同时适用于 qt4.86 和 qt5.5.1。

    所以我认为它以你意想不到的方式工作,因为你认为,当你隐藏你的小部件时,QDockTitleBar::resizeEvent 肯定会被调用。但这并不总是正确的。例如,如果您的隐藏小部件的宽度不是很大,那么您的dockwidget 的宽度由标题栏宽度决定,那么qt5.5.1 中的resizeEvent 将不会被调用。如果您希望在显示/隐藏小部件后始终调用 QDockTitleBar::resizeEvent,您可以使用 QResizeEvent 实例显式调用 QCoreApplication::sendEvent ( QObject * receiver, QEvent * event )

    【讨论】:

    • 问题不在于是否调用了 resizeEvent(),而在于我的停靠小部件的行为。目前,我可以隐藏/显示其中的小部件,但我无法相应地设置标题栏。我将编辑我的问题,因为它似乎被误解了。
    • @IAmInPLS,你同时解决了问题吗?我目前正在尝试使用 pyqt。我认为这是可以翻译的。
    • @Skandix 我设法有这种行为,但不像我在这里问的那样。我将两个小部件放在 QDockWidget 中,一个是我隐藏的(垂直的)。当我按下按钮时,第一个小部件被隐藏,我显示垂直的。
    • @IAmInPLS,我目前正在尝试对用于管理两个分组 Dockwidgets 的 QTabWidget 进行子类化。您可以添加按钮等。在他们那里,他们在窗口中有所需的方向。但我仍然坚持将它们绑定到自然的dockwiget 实现。如果你有兴趣,我可能会在下周发布更新,如果我成功了。
    【解决方案2】:

    您可以尝试从 QDockWidget 中删除然后重新分配您的小部件,而不是隐藏它。

    if(features & QDockWidget::DockWidgetVerticalTitleBar)
    {
        pDock->setFeatures(features ^ QDockWidget::DockWidgetVerticalTitleBar);
        pDock->setWidget(pDockWidget);
    }
    else
    {
        pDock->setFeatures(features | QDockWidget::DockWidgetVerticalTitleBar);
        pDockWidget = pDock->widget();
        pDock->setWidget(0);
    }
    

    【讨论】:

    • 您的信号槽连接良好吗?在你的代码上,我看到你写了 connect(m_pToggleButton, SIGNAL(clicked()), this, SLOT(toggleButtonTriggered()));而不是 connect(m_pToggleButton, SIGNAL(clicked()), this, SLOT(toggleActionTriggered()));
    • 是的,是的,显然连接良好,只是创建 MVCE 时的一个错字
    猜你喜欢
    • 1970-01-01
    • 2017-12-28
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多