3

I have a simple QWidget in a QDockWidget and my own title bar for this dock widget. In this title bar, I put a QPushButton that, when triggered, will allow me to:

  • set the title bar vertical
  • hide the widget inside the QDockWidget

I managed to get both of them working separately, but I can't succeed in doing it simultaneously.

Here is the code for the title bar:

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);
    }           
}

In my main function :

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 : If I change pDock->widget()->hide() in pDock->widget()->show() and vice versa, I almost have the desired behavior, but the widget is hidden when the title bar is horizontal (I want it to be hidden when the title bar is vertical)...

I also put the resizeEvent(). When I trigger the button, title bar horizontal, I have :

I am Vertical

I am Horizontal

I am Horizontal

and if I trigger the button once again :

I am Vertical

I am Horizontal

I am Horizontal

I am Horizontal

Can anyone explain me this behavior and/or tell me what am I doing wrong and how I can fix it?


Edit : I work on Qt5.6, if that matters.

I am not focusing on the resizeEvent() being called or not, it's just the behavior that is not the one wanted. At the moment :

1/ If I use this code :

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

It works like it is supposed to work : the title bar is set vertical when the button is triggered, and back to horizontal when I trigger the button again. Plus, the widget is always shown.

2/ If I use this code :

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

Then, if I trigger the button, the widget is hidden (as wanted), BUT the title bar is not set vertical. If I trigger the button again, the widget is shown (as wanted), and the title bar is still horizontal (seems normal, since it didn't change at the first triggering).

3/ If I use this code (this is where the behavior seems to be near of what I want) :

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

Then :

  • first triggering : title bar set vertical (it is OK) BUT widget still shown
  • second triggering : title bar back to horizontal BUT widget hidden this time
  • third triggering, and after : title bar vertical with widget shown, then title bar horizontal with widget hidden. I would like the opposite, i.e. title bar vertical/widget hidden and title bar horizontal/widget shown.
IAmInPLS
  • 4,051
  • 4
  • 24
  • 57

2 Answers2

2

First of all I tried to compile your example with qt4.86 and qt5.5.1. And they behave a little bit different. With qt4.86 I think it works fine. But with qt5.5.1 it really shows "I am Horizontal" as you described. I don't know why they differ, but they do.

By the way it works on both qt4.86 and qt5.5.1 when I deattach QDockWidget from mainwindow.

So I think it works in the way you don't expect because you think that, when you hide your widget, QDockTitleBar::resizeEvent will be certainly called. But it is not always true. For example if the width of your hiding widget is not very big and so the width of your dockwidget is determined by the titlebar width, then resizeEvent in qt5.5.1 will not be called. If you want your QDockTitleBar::resizeEvent to be always called after showing/hiding of your widget you can explicitly call QCoreApplication::sendEvent ( QObject * receiver, QEvent * event ) with QResizeEvent instance.

Ilya
  • 4,583
  • 4
  • 26
  • 51
Seleznev Anton
  • 641
  • 5
  • 14
  • The problem is not on the resizeEvent() being called or not, it is on the behavior of my dock widget. At the moment, I can hide/show the widget within, but I can't set the title bar accordingly. I will edit my question since it seems to be misinterpreted. – IAmInPLS Jun 20 '16 at 07:36
  • @IAmInPLS, did you solved to problem meanwhile? I'm currently trying the same with pyqt. I think this is translatable. – Skandix Mar 14 '18 at 13:52
  • @Skandix I managed to have this behavior, but not like the way I asked here. I put two widgets in a QDockWidget, one that I hide (the vertical one). When I push the button, the first widget is hidden, and i show the vertical one. – IAmInPLS Mar 15 '18 at 10:35
  • 1
    @IAmInPLS, I'm currently experimenting with subclassing the QTabWidget that is used to manage two grouped Dockwidgets. You can add button, ect. in their too and they have the desired direction in the window. But I'm still stuck on binding them to the natural dockwiget implementation. If you are interested I may post an update on that next week, if I have success. – Skandix Mar 15 '18 at 11:47
0

You may try to remove and then reassign your widget from the QDockWidget instead of hiding it.

if(features & QDockWidget::DockWidgetVerticalTitleBar)
{
    pDock->setFeatures(features ^ QDockWidget::DockWidgetVerticalTitleBar);
    pDock->setWidget(pDockWidget);
}
else
{
    pDock->setFeatures(features | QDockWidget::DockWidgetVerticalTitleBar);
    pDockWidget = pDock->widget();
    pDock->setWidget(0);
}
Daniele
  • 26
  • 3
  • 1
    Is your signal-slot well connected? on your code I see you wrote connect(m_pToggleButton, SIGNAL(clicked()), this, SLOT(toggleButtonTriggered())); instead of connect(m_pToggleButton, SIGNAL(clicked()), this, SLOT(toggleActionTriggered())); – Daniele Jun 20 '16 at 15:20
  • Yes, yes, it is well connected obviously, just a typo when creating a MVCE – IAmInPLS Jun 20 '16 at 15:24