How to find the height of a QDockWidget title bar? - c++

I'm trying to find the height of a QDockWidget title bar in order to do some intelligent sizing of a custom layout, but the title bar is not a separate widget, it's built into the private layout of the dock widget, and there is no member to access it. Is there some other way to find its height?

Yes, you can find the title bar's height using the pixelMetric member function of the dock's QStyle element. You'll probably also want to query the margin as well since it adds space around the title bar and the layout will need to be aware of it. Example:
QDockWidget * myDock = new QDockWidget;
int titleBarHeight = myDock->style()->pixelMetric(QStyle::PM_TitleBarHeight);
int titleBarMargin = myDock->style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin);

You can always run QObject::findChild wih a suitable type or object name to find otherwise inaccessible children.

Related

How can i add dynamically widget into a widget's layout in QT

What i want to do is to add a widget in a widget's layout dynamically:
my_widget->layout()->addWidget(another_widget);
but sadly layout() method is an accessor.
Another way to do this is use the ui variable of the MainWindow,
ui->my_widget_layout->addWidget(another_widget);
which gives me direct access to widget's layout.
Is there another way to do this ?
Thank you.
What's wrong about layout() being an accessor? It works! It returns QLayout *, and you can add other widgets to it. Make sure you show() these widgets if the parent is already visible.
You can also cast layouts, if you think being more specific would be useful in a particular layout:
auto *grid = qobject_cast<QGridLayout*>(parent->layout());
if (grid)
// Add in the second column
grid->addWidget(widget, grid->rowCount(), 1);
else
parent->layout()->addWidget(widget);
widget->show();

How to change the size of a QComboBox's QScrollBar?

I'm using a QComboBox with some items to the point that, when the widget that shows all available items in the QComboBox appears, only some of the items are visible with the other accesible through a QScrollBar.
The problem is that the QScrollBar is to thin and I want to make it larger. I did some research on the web and I did found some ways to change the QScrollBar's width (see references below), but the problem is that I simply can't find the method to access the QComboBox's QScrollBar.
So, given this problem, how can I do this change? (I guess you may either present me with a way that don't require me to access the QScrollBar or show how may I access it).
References:
vertical scrollbar width - Direct access and style
How to get scroll bar real width in Qt? - Again by pixlMetric (only access)
How to increase QTableWidget Vertical Scrollbar width? - Using stylesheet (a preferable method if there is a way to make it apply to all QScrollBars available in the project)
Other options are discussed here
Get the combobox's QAbstractItemView via view()
That class inherits from QAbstractScrollArea, thus inherits the verticalScrollBar method
e.g.
QAbstractItemView *qv = combobox.view();
QScrollBar *scrollbar = qv->verticalScrollBar();
// Adjust size via setStyleSheet or hint/width
The scroll bar isn't a member of the QComboBox class, it's a member of the underlying QAbstractItemView. Try something like the following (pseudo-code):
QListView* abby = new QListView();
QWidgetList list = abby->scrollBarWidgets(Qt::AlignRight);
for (auto itr = list.begin(); itr != list.end(); itr++)
{
(*itr)->setMinimumWidth(100);
}
QComboBox combo;
combo.setView(abby);
The scrollbarwidgets returns a widget list of the scroll bars for that alignment. You can then set the properties on the scroll bar pointers.

Widget same size as it's children?

In Qt, how can I have a widget which automatically sizes itself according to the size of it's children?
For example, if I have a QGroupBox which contains a QHBoxLayout which contains some QPushButtons, I would like the QGroupBox to automatically calculate it's size so that it is no bigger and no smaller than necessary to fit all of the QPushButtons.
Ideally I would like to be able to do this in Qt Designer so that I can create a .ui file which already knows how to size the QGroupBox, however I am also opening to deriving from a class inside a .ui file and doing the resizing manually.
I have tried placing the QGroupBox inside it's own layout (with and without a spacer) but this just resizes the QGroupBox to the smallest possible size so that none of the children are visible.
There are two things to pay attention to:
Set the size policies appropriately on the children in the groupbox. You literally need to think what the buttons can do - most likely, you do not want the buttons to either grow or shrink, so setting both of their size policies to Fixed is the right thing to do. You could, possibly, let the buttons expand horizontally, so the horizontal policy of MinimumExpanding is an option.
Set the size constraint on the layout in the groupbox to act according to your objective:
ui->groupbox->layout()->setConstraint(QLayout::SetMinAndMaxSize);
Of course, the groupbox will be inside of some layout in its parent window, but that doesn't matter.
You'll probably have the most luck by sub classing QGroupBox and overriding sizeHint or other sizing functions to loop through children and calculate the minimum bounding rectangle. Depending on how dynamic the group box is, managing connections to new widgets might be a small challenge.

resize problem in scroll area

Hello everyone, here is my code:
myplot *p = new myplot(gao.structpayloadgraph,
gao1.structpayloadgraph,
gao.structcol-2, "payload");
ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->scrollArea->setWidgetResizable(false);
p->resize(ui->scrollArea->size().width(), ui->scrollArea->size().height());
ui->scrollArea->setWidget(p);
I want p to take up the full available space of the scrollbar area and fit itself. However, the appearance looks 'squeezed' even though I called the resize function. What should I do to achieve the desired effect?
You have to treat the scroll area content widget as a normal QWidget. If you want automatic resize and you must use layouts in Qt. Try the following :
QVBoxLayout layout = new QVBoxLayout( ui->scrollAreaContent);
layout->setMargin(0);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
ui->scrollAreaContent->setLayout( layout);
layout->addWidget(p);
NOTE: ui->scrollAreaContent is a guess, but I think you are using ui files and default content widget is named like that ...
Go to the top right of the QT creator designer screen (Object, Class), right click on the QScrollArea row and select the "Lay Out" menu item, choose a layout (eg vertical or horizontal layout), make sure that your QWidget has a minimum or above size policy. Your scroll widget should now resize with the layout.

How to draw a progress bar inside a list widget in Qt

I want to have a list of items that need to be processed in a QListWidget. Similar to Windows Media Player CD import, there should be a progress bar for every item in the list.
Now there seems to be a way to do this by creating a regular progress bar, using QPixmap::grabWidget() to save its appearance in a QPixmap and then adding this QPixmap as Icon to the QListWidgetItem via QListWidgetItem::setIcon().
However, this seems to be horribly wacky.
Do you know a more elegant way to achieve a progress bar inside a list widget?
Each item in a QListWidget can be represented by a QWidget of your choice, rather than the default rendering (text). You can set this by calling QListWidget::setItemWidget(). In this case, I'd recommend using QProgressBar as the rendering widget -- you should get the desired result.
From the documentation of QListWidget::setItemWidget():
This function should only be used to
display static content in the place of
a list widget item. If you want to
display custom dynamic content or
implement a custom editor widget, use
QListView and subclass QItemDelegate
instead.
You could do it by converting your list widget into a model/view/delegate combo. Then you can set a delegate on the list view that overrides the paint functions and draws the progress bar wherever you want it. I don't know how easy it would be to get an actual QProgressBar widget into the drawing area, however.
Alternately, you could consider making your own list-widget like container that knows about the progress bars.