I have a QComboBox that I fill with QString using:
comboBox->addItem(someString);
When I start my GUI application the width of the QComboBox is always 70, even if the smallest item is much larger. How can I dynamically set the width of a QComboBox, for instance, to the largest QString within the comboBox?
Edit:
After some further testing I found the following solution:
// get the minimum width that fits the largest item.
int width = ui->sieveSizeComboBox->minimumSizeHint().width();
// set the ComboBoxe to that width.
ui->sieveSizeComboBox->setMinimumWidth(width);
Qt (4.6) online documentation has this to say about QComboBox:
enum SizeAdjustPolicy { AdjustToContents, AdjustToContentsOnFirstShow, AdjustToMinimumContentsLength, AdjustToMinimumContentsLengthWithIcon }
I would suggest
ensuring the SizeAdjustPolicy is actually being used
setting the enum to AdjustToContents. As you mention a .ui file I suggest doing that in Designer. Normally there shouldn't be anything fancy in your constructor at all concerning things you do in Designer.
According to the docs the default SizeAdjustPolicy is AdjustToContentsOnFirstShow so perhaps you are showing it and then populating it?
Either populate it first before showing it or try setting the policy to QComboBox::AdjustToContents.
Edit:
BTW I'm assuming that you have the QComboBox in a suitable layout, eg. QHBoxLayout, so that the size hint/policy is actually being used.
I was searching for a solution to only change the size of the dropdown menu of the combobox to fit the largest text without changing the size of the combobox itself.
Your suggestion (#Linoliumz) did help me find the solution. Here it is :
Suppose you have a combobox called cb:
C++:
width = cb->minimumSizeHint().width()
cb->view().setMinimumWidth(width)
PyQT :
width = cb.minimumSizeHint().width()
cb.view().setMinimumWidth(width)
Related
I have a column in my QTableWidget whose contents are of variable length. It's important that the entirety of this content is visible (no ...), but I want to provide only as much space as is required. Here is the code I have to accomplish this.
... In the form's constructor
ui->myTable->horizontalHeader()->setResizeMode( 1, ResizeToContents );
ui->myTable->horizontalHeader()->setStretchLastSection( true );
...
This works with the exception that the specified column is sized to fit the largest item which is currently visible (on screen), meaning that any would be wider columns are left to narrow, and end with "..." and truncated content. Alternatively, I've tried the following:
... Populate the table ...
ui->myTable->resizeColumnToContents( 1 );
...
Unfortunately this seems to behave the same as the first code snippet, only considering visible columns when resizing.
How can I get the column to resize considering all items in the row, not only those that are visible?
Since you have tagged this as qt4, I suspect this to be caused by a bug as seen here: https://bugreports.qt.io/browse/QTBUG-4206
This bug causes the table to only resize the items that are currently in its viewport and is fixed for versions >= 5.2. You might solve this in subclassing QHeaderView, but this seems like a rather exhausting approach. If feasible, I would suggest you switch to a newer Qt version.
upon construction of QTreeWidgetItem you can pass a list of strings, so when you insert it in a table(QTreeWidget), you get the strings listed on a row. However, from the methods of the table you can also call setItemWidget and set a text widget or any sort of widget to be in that row, but it seems incompatible with having a string list, since the widget is drawn over the strings. There is also a setData method for the QTreeWidgetItem, which sets some data that can be retreived, but isn't visible to the user. Is there a cookie-cutter way of properly using all three data storage methods? Are they even compatible or must I stick to only one?
The Constructor of QTreeWidgetItem is convenient to immediately list the desired content.
When inserting a custom widget in a cell, you need to change its autoFillBackgroundproperty to true, so that it is not transparent. See the QTreewidget::setItemWidget description:
The given widget's autoFillBackground property must be set to true,
otherwise the widget's background will be transparent, showing both
the model data and the tree widget item.
QTreeWidgetItem::setData can be used when already having an item and you want to change one of its contents.
Of course you can combine any of these methods, but it is hard to say, which approach is best without knowing your use case. Just one more hint: If you just need a plain stupid representation of data that does not change, using QTreeWidget is fine. But if your displayed data can change, e.g. objects get deleted, added, changed in various locations of your code, a QTreeView with a custom data model might be a better choice.
In a QTableWidget I can configure the rows to be resizable by the user on run time by setting the verticalHeader's resizeMode to Interactive like this:
table.verticalHeader().setResizeMode(QtGui.QHeaderView.Interactive)
How would I configure a similar behavior for QListWidget? Unfortunately the QListWidget resizeMode does not have an Interactive item and I haven't found anything similar.
The best would be to configure it for the whole list but when it's possible for single rows/items that would be ok, too.
As doc said:
This view does not display horizontal or vertical headers; to display
a list of items with a horizontal header, use QTreeView instead.
So you should use QTreeView (or QTreeWidget) with one column and maybe with specific style.
Another approach. There are no header, so you can provide some instrument (dialog window, slider or something else) where user will be able to change row height, to change row height you should just use setData() and set QSize() to Qt::SizeHintRole. For example:
ui->listWidget->model()->setData(ui->listWidget->currentIndex(),
QSize(40,40),Qt::SizeHintRole);
I want to change the color and the text of items displayed by a QComboBox, depending on some conditions, but without changing the data in the model itself.
I figured out how to change the color, which was rather easy:
//---------------------------------------------------------------------------------
void
ComboPriorityDelegate::paint(QPainter* p_painter, const QStyleOptionViewItem& p_option, const QModelIndex& p_index) const
{
QStyleOptionViewItem newOption(p_option);
// Set the color
newOption.palette.setColor(QPalette::Text, QColor(255, 0, 0));
QItemDelegate::paint(p_painter, newOption, p_index);
}
Just to explain, in my actual code, I have some conditions there, so I do not want to modify each item.
However, I cannot figure out how I would change the displayed text. I tried setting the text property of the newOption, but it seems like that has nothing to do with the actual text being displayed.
In addition, I need to change the text back to its original form as soon as the item is selected.
I found out that p_index.data().toString() gives me the displayed text, but that doesn't help me modifying it. What I need is an easy way to modify the text attribute of the QLabel (or whatever the QComboBox uses to display item text), without affecting the model itself.
I know that there would be workarounds, like remove the item from the combo box that I want to change and inserting a changed version, but I hope that there is an easier way.
Adding a proxy model on top of your model and changing its data() method seems the easiest solution to me.
There is QIdentityProxyModel which you can simply subclass and override data(). Use your original model as the proxy model's source, and the proxy model as the combobox's model.
Actual Answer:
It seems that what I want to do is simply not possible just using a delegate.
Workaround:
So what I did instead was using an event filter to set the correct suffix for the item texts as well as their color before the drop-down opens (listen to MousePressed event).
And to make sure that the text suffix is removed when an item is selected, I added a slot to the event filter class that must be connected to the activated() signal of the QComboBox. That slot then checks for the suffix and removes it.
This is not a nice thing, but at least it requires only one additional class and two lines of code to make use of. And it should be independent of the data model used.
I feel really silly asking this question but how do you add any data to a Combo Box? Like I want to display A,B and C as my dropbox strings but I have tried out many things, still my Combo Box does not display anything.
I have tried setting the 'Data' property with A;B;C..still it doesn't show this.
I tried this in my Oninitdialog() function:
CComboBox* pComboBox = (CComboBox*)GetDlgItem(IDC_SENSOR_LIST);
CString string;
for(int i=0;i<10; i++)
{
string.Format("String %d", ++i);
pComboBox->AddString(string);
}
..
still no change. It may be I might not be doing something really silly but not able to figure it out at the moment. Kindly help.
Cheers.
Make sure your combobox has a height that can hold all entries. The height of a combo box doesn't affect the combo box itself, but the dropdown list.
You can change it in the dialog editor:
Click on the down arrow of the combo box, now there should be a rectangle that allows you to change the height of the combobox dropdown list. Make it large enough to hold all entries.