隐藏QDockWidget的小部件并同时设置垂直标题栏

时间:2016-06-15 10:02:28

标签: c++ qt qdockwidget

我在QWidget中有一个简单的QDockWidget和我自己的停靠小部件的标题栏。在这个标题栏中,我设置了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);

注意:如果我在 pDock->widget()->hide() 中更改 pDock->widget()->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);
}  

然后:

  • 首次触发:标题栏设置为垂直(可以)但仍显示小部件
  • 第二次触发:标题栏回到水平但这次隐藏的小部件
  • 第三次触发,然后:标题栏垂直显示小部件,然后标题栏水平,小部件隐藏。我希望相反,即标题栏垂直/小部件隐藏标题栏水平/小部件显示。

2 个答案:

答案 0 :(得分:2)

首先,我尝试用qt4.86和qt5.5.1编译你的例子。而且他们的行为有点不同。使用qt4.86我认为它工作正常。但是对于qt5.5.1,它确实显示了#34;我是横向的&#34;如你所描述的那样我不知道他们为什么会有所不同,但确实如此。

顺便说一下,当我从主窗口中取消QDockWidget时,它对qt4.86和qt5.5.1起作用。

所以我认为它的运作方式与你期望不同,因为你认为,当你隐藏你的小部件时,QDockTitleBar::resizeEvent肯定会被调用。但并非总是如此。例如,如果隐藏窗口小部件的宽度不是很大,因此dockwidget的宽度由标题栏宽度决定,则不会调用qt5.5.1中的resizeEvent。如果您希望在显示/隐藏窗口小部件后始终调用QDockTitleBar::resizeEvent,则可以使用QCoreApplication::sendEvent ( QObject * receiver, QEvent * event )实例显式调用QResizeEvent

答案 1 :(得分:0)

您可以尝试删除然后从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);
}