Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With QToolBox, which setting to have page be only its content size?

Tags:

c++

qt

I'm trying to find the settings or size policy so that each page in my QToolBox instance only takes up the space needed by its content. I've tried everything I could see in the properties for both the instance and for each of the individual pages.

Am I misconstruing the functionality of QToolBox widget or just missing the right setting?

What I am going for is something similar to the accordion fold type widget in Qt Creator:

enter image description here

I can't seem to get this "Sort" page to take only the size needed to display the button and field.

enter image description here

enter image description here

like image 829
spring Avatar asked Sep 02 '13 14:09

spring


2 Answers

Unfortunately you can't do that directly because it will span all the available space that the title widgets don't occupy. You can emulate what you want by setting a fixed height on the QToolBox if you know the exact height your page(s). But you do not want to do that in practise.

If you want the behavior you ask for then you need to write your own custom control. It doesn't have to be hard. Use a QVBoxLayout and fill into it items of a custom class, let's call it ToolItem, which is a QWidget with a title (perhaps a button to show/hide) and another QWidget for showing the contents that is either visible or not.

The following very simple example will toggle the visibility of the ToolItem when it is clicked. And only when visible will it occupy any space.

class ToolItem : public QWidget {
public:
  ToolItem(const QString &title, QWidget *item) : item(item) {
    QVBoxLayout *layout = new QVBoxLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(new QLabel(title));
    layout->addWidget(item);    
    setLayout(layout);

    item->setVisible(false);
  }

protected:
  void mousePressEvent(QMouseEvent *event) {
    item->setVisible(!item->isVisible());
  }

private:
  QWidget *item;
};

class ToolBox : public QWidget {
public:
  ToolBox() : layout(new QVBoxLayout) {
    setLayout(layout);
  }

  void addItem(ToolItem *item) {
    // Remove last spacer item if present.
    int count = layout->count();
    if (count > 1) {
      layout->removeItem(layout->itemAt(count - 1));
    }

    // Add item and make sure it stretches the remaining space.
    layout->addWidget(item);    
    layout->addStretch();
  }

private:
  QVBoxLayout *layout;
};

And simple usage of it:

QWidget *window = new QWidget;
window->setWindowTitle("QToolBox Example");

QListWidget *list = new QListWidget;
list->addItem("One");
list->addItem("Two");
list->addItem("Three");

ToolBox *toolBox = new ToolBox;
toolBox->addItem(new ToolItem("Title 1", new QLabel("Some text here")));
toolBox->addItem(new ToolItem("Title 2", list));
toolBox->addItem(new ToolItem("Title 3", new QLabel("Lorem Ipsum..")));  

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(toolBox);

window->setLayout(layout);
window->resize(500, 500);
window->show();

You can now tweak it to look like the QToolBox if needed.

Please don't hesitate to ask follow-up questions.

like image 134
Morten Kristensen Avatar answered Oct 12 '22 01:10

Morten Kristensen


The example shown from Qt Designer may not be using a QToolBox, which behaves more like a stacked tab widget only displaying a single page at a time. The example in Qt Designer appears to be a QTreeWidget with custom drawing or styling.

like image 31
Jason Avatar answered Oct 12 '22 02:10

Jason