QListWidget - Removing Padding & Consistent Column Width - c++

I created a QListWidget using setViewMode(QListView::ListMode) and setFlow(QListView::TopToBottom) to get this:
The large space between the icon and the text looks odd so I tried to remove it with:
list->setStyleSheet("QListView::icon { padding-right: 0px; }");
and also:
list->setStyleSheet("QListView::icon { padding: 0px; }");
but neither removes the space. Is there any way to remove the space between the icon and the text?
Also, you'll see from the above screenshot that QListWidget uses variable column widths, but I wanted all the columns to have the same width. I tried this solution:
int width = 0;
int numItems = list->count();
QFontMetrics metrics(list->font());
for (int i = 0 ; i < numItems ; ++i)
{
if (metrics.boundingRect(list->item(i)->text()).width() > width)
width = metrics.boundingRect(list->item(i)->text()).width();
}
list->setGridSize(QSize(width+30, 16));
However, it doesn't seem to work consistently and I had to use +30 to account for the icon area, which isn't a very good solution, particularly if the size of the icon changes.
Is there a better way to get all the columns the same width?

Related

How can I resize QTableView row according to specific cell value?

I want to resize the row height according to a specific column value. For example, the table I want to change is here:
At row 10, row height is resized by the third column value. But at row 11 it is resized by the second column value. I want to resize row height by only the third column value. Is there a way to do this?
Thank you.
This is my code for this QTableView
ui->tableView->setModel(modal);
ui->tableView->hideColumn(0);
ui->tableView->resizeColumnsToContents();
ui->tableView->resizeRowsToContents();
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView { font-size: 18pt; color:#002B5B; font-weight: bold; }");
I haven't actually tried it myself, but from looking at the Qt source code (in particular the source code for QTableView::rowHeight(int) const and QHeaderView::sectionSizeFromContents(int) const), it looks like you could do something like:
const int addressColumnLogicalIndex = 1; // i.e. 2nd column in the table
const int fixedRowHeight = 18; // or whatever fixed height you want the address-column to use
model()->setHeaderData(addressColumnLogicalIndex, Qt::Vertical, QSize(0, fixedRowHeight), Qt::SizeHintRole);

Firemonkey: Shrink text font to fit in TLabel

I am attempting to lower the font size of a TLabel if its text is to large to fit in the confines of the label. I didn't see any properties I could set on the label to achieve this, so I have tried writing my own method. My method works by using TCanvas.TextWidth to measure the width of the text in a label, and shrink the font until the width of the text fits within the width of the label.
void __fastcall ShrinkFontToFitLabel( TCanvas * Canvas, TLabel * Label )
{
float NewFontSize = Label->Font->Size;
Canvas->Font->Family = Label->Font->Family;
Canvas->Font->Size = NewFontSize;
while( Canvas->TextWidth( Label->Text ) > Label->Width && NewFontSize > MinimumFontSize )
{
NewFontSize -= FontSizeDecrement;
Canvas->Font->Size = NewFontSize;
}
Label->Font->Size = NewFontSize;
}
This works some of the time, however other times it does not shrink the font near enough. It seems as if the value I get from calling Canvas->TextWidth is a lot of times, much smaller than the number of pixels wide the label actually needs to be in order to fit the text.
Am I using Canvas->TextWidth incorrectly? Is there a better way to calculate the width of a string, or to re-size the font of a TLabel so its text fits within its demensions?
Edit:
In this case, I am passing in to my function, the TCanvas that my label is sitting in. I have tried using that TCanvas as well as Label->Canvas. Both give me the same number for text width, and both are short of the actual value in pixels needed to display the whole string.
The following code is taken from code that works in an FMX application, modified slightly to remove arrays that are being iterated through and declaring a variable locally to the function. It is being run in a TForm method. Canvas here is the Form's Canvas. You can see that I'm using "- 35" at one point - this might be because the numbers weren't quite right.
double InitialFontSize = 30;
Canvas->Font->Size = InitialFontSize;
StoryHeadlineLabel->Font->Size = InitialFontSize;
bool fits = false;
do
{
double widthA = Canvas->TextWidth (StoryHeadlineLabel->Text);
if (widthA > StoryHeadlineLabel->Width - 35)
{
StoryHeadlineLabel->Font->Size --;
Canvas->Font->Size --;
}
else
fits = true;
if (StoryHeadlineLabel->Font->Size < 6)
fits = true;
} while (!fits);

QPushButton resize after changing color

I want to modify the background-color of QPushButtons. The problem is that modifying the background color using setStyleSheet("QPushButton { background-color: #00FF00 }"); , the button size also scales.
before
after
I understand that by changing the background-color, the entire button style sheet gets overwritten and reset to some default (How to override just one property:value pair in Qt StyleSheet).
My question is: how can I set the size of the button such that it is the same size as the original?
I am using MacOSX and I tried all combinations of height, minimum-height, padding.
If it's just about setting the background color, then using the QPalette would be an option.
QPushButton button;
QPalette palette = button.palette();
palette.setColor(QPalette::Background, QColor("#00FF00");
button.setPalette(palette);
I thinks it's because min-width and min-height are not specified.
According to the documentation:
If this property is not specified, the minimum width is derived based
on the widget's contents and the style.
One possibility could be to get the size of the button before setting the style, and set that size when you apply the background color.
I.e. (in this example, we have a UI file with a pushbutton called pushButton):
QString width ("min-width: " +
QString::number(ui.pushButton->size().width()) +
" px; " +
"max-width: " +
QString::number(ui.pushButton->size().width()) +
" px;");
QString height ("min-height: " +
QString::number(ui.pushButton->size().height()) +
" px; " +
"max-height: " +
QString::number(ui.pushButton->size().height()) +
" px;");
QString style ("#pushButton { " + width + height +
"background-color: black; }");
qApp->setStyleSheet(style);
I'm setting both min and max width and height because the reference says
If you want a widget with a fixed width, set the min-width and
max-width to the same value.
Of course, an easier solution could be to resize the pushbutton after setting the background color. Something like this:
int width = ui.pushButton->size().width();
int height = ui.pushButton->size().height();
QString style ("#pushButton { background-color: black; }");
qApp->setStyleSheet(style);
ui.pushButton->resize(width, height);

QTreeWidget border radius toggles visibility during scrolling when set alternating row colors

I am trying to design a QTreeWidget with border-radius. The problem sets in when I assign alternate row colors to it. When I don't, it works fine, and the border-radius around the widget is always visible during scrolling. However, when I scroll with the alternate row colors set, during even numbered rows being at the top and bottom, the border-radius remains as expected, while during odd numbered ones, they are eclipsed, with the look and feel of a widget with no border-radius. Here's what it looks like when the grey colored rows are at the top and bottom:
And after you scroll one unit, or odd number of units, so that the white colored rows are at the ends, this is what it looks like:
How do I fix this? And in Windows, because the scrollbars are differently styled, the right side will always have the border radius eclipsed due to the scroll pane. Is there a way to make it behave just like the Mac scrollbar?
My style sheet is pretty minimal:
#myTreeWidget {background-color: #C2C7CB; border-radius: 8px; }
I set the width of the rows through a delegate:
class ItemDelegate : public QItemDelegate
{
public:
ItemDelegate()
{}
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
return QSize(240,25);
}
};
ItemDelegate *delegate = new ItemDelegate();
myTreeWidget = new QTreeWidget(this);
myTreeWidget->setObjectName(QString::fromUtf8("myTreeWidget"));
myTreeWidget->setAttribute(Qt::WA_MacShowFocusRect,false);
myTreeWidget->setGeometry(QRect(20, 10, 240, 375));
myTreeWidget->headerItem()->setHidden(true);
myTreeWidget->setItemDelegate(delegate);
myTreeWidget->setAlternatingRowColors(true);
I just observed a weird thing. If I remove the background color from the widget, the border radius completely disappears. Not visible under any circumstance!

How to change the color of the text of a QProgressBar with its value?

I don't know how to change the color of the text partially in the progress bar when its value becomes nearly 50%. This effect comes automatically in the fusion style progress bar (picture below). Does anyone know how this is done ?
Too lazy to write working example code, much less making a screenshot. Not even for 50 reps. :-)
However, the question was somewhat interesting. I had no idea how such a two colored text could be done. So I checked:
http://qt.gitorious.org/qt/qtbase/blobs/stable/src/widgets/styles/qfusionstyle.cpp
Line 1450ff (http://qt.gitorious.org/qt/qtbase/blobs/stable/src/widgets/styles/qfusionstyle.cpp#line1450).
QRegion rightRect = rect;
rightRect = rightRect.subtracted(leftRect);
painter->setClipRegion(rightRect);
painter->setPen(flip ? alternateTextColor : textColor);
painter->drawText(rect,
bar->text,
QTextOption(Qt::AlignAbsolute|
Qt::AlignHCenter|
Qt::AlignVCenter));
if (!leftRect.isNull())
{
painter->setPen(flip ? textColor : alternateTextColor);
painter->setClipRect(leftRect);
painter->drawText(rect,
bar->text,
QTextOption(Qt::AlignAbsolute|
Qt::AlignHCenter|
Qt::AlignVCenter));
}
Basically the text is drawn two times into the same rectangle. Each time with an appropriate clipping. Easy if you know how. :-)
From my point of view the best, and probably the easiest, way to do this is to change the pallet for the QProgressBar widget:
QPalette palette = progressBar->palette()
palette.setColor(QPalette::Text, textColor)
palette.setColor(QPalette::HighlightedText, textColor)
progressBar->setPalette(palette)
"The setBackgroundRole method let you use a color role for the background, which means one of the predefined color of the style applied to the widget. So your are basically limited to the style and its colors."
Background solution:
value = 65
self.progressBar.setProperty("value", value)
if value < 50:
self.progressBar.setStyleSheet("QProgressBar::chunk { background-color: black; }")
else:
self.progressBar.setStyleSheet("QProgressBar::chunk { background-color: black; } QProgressBar { color: white; }")
You can use stylesheet on the Container Widget :
myMainWidget.setStyleSheet(QString("QProgressBar {color: red}"));