QSlider with ticks not properly drawn - c++

Enabling a ticks for QSlider seems to mess up the sizeHint of the slider itself.
Consider this simple code:
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSlider ds{Qt::Horizontal};
ds.setRange(0, 100);
ds.setTickPosition(QSlider::TicksAbove);
ds.setTickInterval(20);
ds.show();
return a.exec();
}
and this is how is rendered:
notice how the slider is cropped below.
this behaviour is the same in a complex widget too of course:
Resizing the window of the first slider tick position does not follow the slider itself.
So the question is how have a QSlider rendered properly with ticks enabled?

I would recommend to add VerticalSpacers at the top and bottom, which are set to "expanding" So that the slider is sandwiched. So when you resize the whole widget, for vertical changes th slider stays minimumHeight, but for horizontal changes it expands (at least this is what I expect what you want to achieve).

The practical way I found to solve this is to set the minimum size manually to the bare minumum to avoid the incorrect render:
ds.setMinimumHeight(30);

Related

ubuntu sdk qml Quick view window close, minimize button not visible

This is my first time using QT and the Ubuntu SDK. In order to restrict the view size, i set a minimum and maximum height/width for the view:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:///main.qml")));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setMaximumHeight((600));
view.setMaximumWidth((800));
view.setMinimumHeight((600));
view.setMinimumWidth((800));
view.show();
return app.exec();
}
However after adding the Max/min height/width attributes, the minimize and close buttons have disappeared from the application. Any way i can bring them back while maintaining the restriction of the view size? I have tried searching but couldn't find similar issue.
Thanks.
A quick workaround is to use setMaximumHeight/Width and set them to +1.
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:///main.qml")));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setMaximumHeight((601));
view.setMaximumWidth((801));
view.setMinimumHeight((600));
view.setMinimumWidth((800));
This way the window can't resize any more than that 1 pixel and at the same time, the minimize, close buttons don't disappear.

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

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.

Disable resizing of a form

I want to disable resizing my form - here is what I have tried.
I have changed the resize policy of the form to the following
HorizontalPolicy:Fixed
VerticalPloicy: Fixed
I have also tried the following
Form *w = new Form();
w->setFixedSize(w->size());
w->show();
But the form still gets resized by dragging the corners. Any suggestions ?
It definitely has to be possible.
Firstly you should know, that before window is actually shown it has no information of it's size - so size will probably return 0 (or invalid; or anything ;) ) at this point - it would probably mess up entire sizing and is therefore silently rejected. I would try
Form *w = new Form();
//w->ensurePolished();
w->setFixedSize(w->sizeHint());
w->show();
Size hint should have correct value no matter what. QWidget::ensurePolished() might be necessary here, but I recommend trying first without it - if it works, why complicate things?
If it still doesn't work, then you can simply try overriding resizeEvent() and setting the only right size for your widget if user resizes it to anything else. This will still give user an illusion of resize-ability (cursors changes on the edges and so on), so it's really the last option.
EDIT:
#include <QtGui/QApplication>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.setFixedSize(500,500);
w.show();
return a.exec();
}
Result: widget cannot be resized. So it is not change to QMainWindow that helped - oat least on my system a simple widget can do it too ;)

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.

Is it possible to set the opacity of qt widgets?

I know that there is a function QWidget::setWindowOpacity(qreal level) but as written in the documentation this does only work for windows.
Is there a way to make widgets that are lying inside layouts opaque too?
What I'm trying to do is an animation where widgets are fading in. I once did that with a preferences-dialog and there it worked.
So do you think there is a way or a work-around to achieve opacity for widgets inside layouts? How would you do that?
Thanks in advance!
Just use QGraphicsOpacityEffect in order to achieve this effect.
Qt4: http://doc.qt.io/qt-4.8/qgraphicsopacityeffect.html
Qt5: http://doc.qt.io/qt-5/qgraphicsopacityeffect.html
Qt6: https://doc.qt.io/qt-6/qgraphicsopacityeffect.html
Well for widgets inside mainwidow appear to have setAutoFillBackground(False) by default.
to make it fade in fadeout u need to to use QGraphicsOpacityEffect along with setAutoFillBackground(True)
a small example: write inside the widget which is called inside the mainwindow
op=QGraphicsOpacityEffect(self)
op.setOpacity(1.00) #0 to 1 will cause the fade effect to kick in
self.setGraphicsEffect(op)
self.setAutoFillBackground(True)
SetWindowOpacity works for me in Linux. I used code like this to change window opacity, (value is from 0 to 100):
setWindowOpacity(qreal(value)/100);
mywidget.setStyleSheet('background-color:rgba(r, g, b, alpha);')
works for me
In Qt5 you can use css to make widgets transparent
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QDialog dialog;
dialog.setStyleSheet(QLatin1String("#LolButton{color: transparent; background-color: transparent;}"));
QPushButton button(&dialog);
button.setText("Button");
button.setObjectName(QStringLiteral("LolButton"));
QObject::connect(&button,&QPushButton::clicked,[](){
QMessageBox msg;
msg.setText("LolButton omg");
msg.exec();
});
dialog.show();
return a.exec();
}