Change color highlight of icons in QTableView, when the cell is selected - c++

When a cell is selected in QTableView, the icons in it are given a blue highlight, how can I control the color of this highlight or disable it?
I tried setting the QPalette::Highlight but it didn't work.
Edit:
Okay, so I do know how to change the background color and text color and color highlight, but not for an icon. If I return an icon as decoration for a cell, it is given a light blue highlight when the cell is selected. How do I remove this?

You can use style sheets to define the color of your elements. The name of the selected item in your QTableView is selection-background-color. So, changing the color of this element you will chose the background color that your prefer.
#include <QtWidgets/QApplication>
#include <QtWidgets/QTableView>
#include <QStandardItemModel>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
QTableView *table = new QTableView();
QStandardItemModel *model = new QStandardItemModel(2,2);
table->setModel(model);
table->setStyleSheet("selection-background-color: red");
table->show();
return app.exec();
}
Look how it looks in the picture:

I discovered a way around this issue, but it has some cost associated with it.
Fundamentally, deep within Qt code it is calling onto QIcon::paint() and passing QIcon::Selected as the icon mode, so the issue is that the "selected" form of the icon's pixmap at the desired resolution is the one auto-generated by Qt.
I worked around this by setting the Selected form of the icon to be the same as the Normal mode:
// Make the "Selected" version of the icon look the same as "Normal".
for (const auto& size : icon.availableSizes())
{
icon.addPixmap(icon.pixmap(size, QIcon::Normal, QIcon::Off),
QIcon::Selected, QIcon::Off);
icon.addPixmap(icon.pixmap(size, QIcon::Normal, QIcon::On),
QIcon::Selected, QIcon::On);
}
The downside is extra time spent doing this, possibly extra memory to store it, and wasted time generating the selected icons that we're throwing away.
In my case I'm using a QStyledItemDelegate and unfortunately that doesn't give you the ability to more closely influencing how the icon is rendered without completely reimplementing how QStyle::CE_ItemViewItem is rendered in your style.
Come to think of it, if you use a proxy style it wouldn't be too hard to override how CE_ItemViewItem is rendered to not use a selected icon, so that would be an option too.

It's utterly impossible to change this behavior with the standard style in Qt. You need to implement your own specific style in order to work around this.

Related

Issue changing a QPushButton style in Qt

I have created a QPushButton in Qt without applying any style, so it inherits the style from Windows10, with this result:
Then I wanted to change temporary the color of the button, so I used:
pushButton->setStyleSheet("background-color: rgb(255,220,220)")
getting this result:
Already this result does not satisfy me because also the style is slightly different from the original one. Anyway the next step was that the button had to return to the "normal" style when pressed, so I added this command
pushButton->setStyleSheet("background-color: rgb(240,240,240)")
but the result is different from the starting button:
Can you please give me some advice to better manage the style?
Thanks
Actually when you set background-color alone to QPushButton, The background may not appear unless you set some value for border.
Look here for (List of Stylable Widgets: QPushButton)
http://doc.qt.io/qt-5/stylesheet-reference.html
I think in windows 10 for some reason, you are able to see something without even setting border.
But the recommended way is to set some border value.
So try setting border value as said below, and see if it addresses your requirement:
pushButton->setStyleSheet("background-color: rgb(255,220,220);border: none; ")
In the above said link you can find below information:
Warning: If you only set a background-color on a QPushButton, the background may not appear unless you set the border property to some value. This is because, by default, the QPushButton draws a native border which completely overlaps the background-color.
Here are some snippets you may find quite similar and helpful.
I had an Update button which I turned into red Cancel button. Once the update action is finished or cancel is pressed, I restored the original color and text.
// Global variables to save off button state
QPalette update_btn_palette_restore;
QString update_btn_text_restore;
....
// Update button is pressed.
// Save the palette and text.
update_btn_palette_restore = _ui->update_button->palette ();
update_btn_text_restore = _ui->update_button->text ();
// Change the color palette and text
QPalette p=palette();
p.setBrush(QPalette::Button,Qt::red);
_ui->update_button->setPalette(p);
_ui->update_button->setText ("Cancel");
....
// Handler for when either cancel is pressed or update has finished
if(! update_btn_text_restore.isEmpty ()) {
_ui->update_button->setText (update_btn_text_restore);
_ui->update_button->setPalette(update_btn_palette_restore);
}

QDockWidget::background-color not applied when docked

I have a QDockWidget:
I would like to alert the user to certain events by setting the background color of the title bar.
I have achieved this by setting the style sheet for my DockWidget:
void DockWidget::setCriticalAlert()
{
setStyleSheet("QDockWidget { background-color:red; }");
}
The result is this:
The problem is that the background-color doesn't get applied when the QDockWidget is docked:
How can I get the background color to be applied when the QDockWidget is docked?
This is a bug in Qt.
Issue 10537
Quoting from the linked issue:
The problem is that in QDockWidget::paintEvent, there is a
isFloating() condition before drawing PE_FrameDockWidget. We cannot
jsut remove this condition as it would break the other style (that
does not whish to draw frame when the dockwidget is docked) We cannot
either use PE_Widget to draw the frame as then it goes over the
dockwidget's title The solution is maybe to introduce a new
PE_FrameDockWidgetDocked primitive element. Or some
SH_DockWidget_DrawDockedFrame stylehint to draw the frame in every
cases.
a valid workaround seems to be to set the stylesheet of the parent, and use the class-and-id selector. Forgive the python formatted code but the concept is the same - in this case, 'dock' is a QDockWidget which has been given an object name using setObjectName(), and its parent, the QMainWindow, is 'self':
self.setStyleSheet("QDockWidget#"+str(dock.objectName())+"::title {background-color:red}")
In PyQt5.5, this works at runtime, i.e., can be changed on the fly.
I find a solution like this:
Firstly put a frame behind all the widgets of dockwidget's center widget, as the background.
Then set stylesheet for the frame.
By this way, we could change the background color of dockwidget.
Or you can extend the dockwidget and overwrite the function
void QDockWidget::setWidget(QWidget *widget)
using private/qdockwidget_h. and add a frame as this widget's father.

QGraphicsItem scaling produces too large bounding rect

Problem: When using a QGraphicsItem with the flag QGraphicsItem::ItemIgnoresTransformations, the View does not scale properly and shows unnecessary scroll bars.
To reproduce, place a QGraphicsView on a Form and use this code:
#include <QGraphicsScene>
#include <QGraphicsTextItem>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGraphicsScene* scene = new QGraphicsScene();
// Set the scene to the view. Has to be done before
// transformation in order for the problem to occur.
ui->graphicsView->setScene(scene);
// Add some text, make it transformation-invariant.
QGraphicsTextItem* txt = scene->addText("Hello World!");
txt->setFlag(QGraphicsItem::ItemIgnoresTransformations);
// Scale the scene, re-calculate the bounding rect.
ui->graphicsView->scale(10, 5);
QRectF rect = scene->itemsBoundingRect();
scene->setSceneRect(rect);
}
This also works with other Items like QGraphicsEllipseItem or QGraphicsRectItem.
Without setting the flag (simply comment out the line txt->setFlag...), the output is as expected:
However, when the flag is set, I would expect the scroll bar to disappear, because the text clearly fits into the view. But instead it looks like this:
I know that the Scene does only automatically grow, but not shrink to its content, so I am explicitly setting the Scene Rect at the end. But even this does not help.
It seems to me like this is a bug in Qt, but maybe I also simply misunderstood something. Any idea what the problem (and solution) is?
Using Qt 5.5, Ubuntu 14.04.
PS: Yes, the scene is never freed. This is of course no production code ;-)
I had a similar issue with addLine and addEllipse on top of an QImage.
The problem seems to come from the QGraphicsItem::ItemIgnoresTransformations flag that seems to enlarge the scene to hold the "transformed" object placement, but then ignores the transform for placement and size, however the damage is already done because it has incorrectly changed the scene scale.
I have a work-around that might be able to help you.
If you reset the scene scale to a known correct value after positioning the objects that ignore the transform. It will avoid your problem.
For example:
m_firstImageScene->setSceneRect(m_firstImageRect);

Styling QListWidget item widgets: selected state

I have a window which displays tiles, each tile having some set of information. Tiles are arranged in a tabular structure. The way in which this is implemented is, a QListWidget is used to hold tiles and each tile is set as the item widget in QListWidgetItems in QListWidget.
I have styled the tiles using a stylesheet. My problem is, I cannot get a tile highlighted in some way when the tile is selected. If I do not use stylesheets at all, default selected highlighting works. But as soon as I apply styles to tiles, there is no difference in the tile in non selected and selected states.
I tried to do it in following way but it does not work.
.tile
{
/*non selected style*/
}
.tileList::item:selected
.tile
{
/*selected style*/
}
Any idea how I can achieve this?
I solved it in Qt Designer by setting the palette how I wanted it and then put
QListView::item:selected { background: palette(Highlight) }
as the styleSheet. Maybe this helps somebody.
If you want to do it from a central qss, I guess you'll have to remove the ".tile" part from the code in the question.
.tileList::item:selected
.tile <--- remove this line
{
/*selected style*/
}
I could get this done to some extent (not a comprehensive solution), by doing following.
Make tile widget semi transparent.
Set a background color to QListWidgetItem
Set a different background color to QListWidgetItem when selected
Styles:
.titleList::item {
background-color: #fff;
}
.lstSnapQuote::item:selected {
background-color: #5555FF;
}

How to add the common navigation bar to a Meego app?

When using the Meego Touch Framework, the standard MApplicationWindow has the common navigation bar (with the switcher, menu and close buttons) already attached.
For example, the following code:
#include <MApplication>
#include <MApplicationWindow>
int main(int argc, char *argv[]){
MApplication app(argc, argv);
MApplicationWindow w;
w.show();
return app.exec();
}
Creates a blank window with a menu bar that looks similar to this (eg. the switcher button, menu and close button along the top).
However, since the the docs discourage the use of the Touch Framework I want to avoid using it, so how would I create a similar looking window using only the standard API?
How I would implement this, would probably be a fixed height, variable width QHBoxLayout with a stretch factor for those indices that need it. Then I would just use QPushButton and QCombobBox for the widgets and finish them off with a custom stylesheet and icons. I would then wrap these inside a neat little custom widget that I could reuse in my main view class.
The main view should be a window class that would hold the navigation bar widget on top of a QVBoxLayout, and the actual content below it. The bottom index would have a stretch factor to it, so that the upper index would always be at the top.
I don't quite remember how the Meego handset UX should act like, but that's how I would create a similar looking navigation bar.
I would just go with the QMainWindow class, as this class already has menus, toolbars, statusbar aso.
You should however take care of the orientation switching yourself (I see that the toolbar in portrait mode is at the bottom, while in landscape mode it is on the top).
This could be accomplished by setting the right Qt::ToolbarArea value.
The style of the buttons and the window itself, can be set using a Qt stylesheet.