GTK3: Getting a style's class property - qt

I'm trying to get the text color of a class of a GTK style.
I have a GtkStyleContext with the widget path and the classes that I want to get their properties.
GtkWidgetPath* widgetPath = gtk_widget_path_new ();
gtk_widget_path_append_type(widgetPath, GTK_TYPE_WINDOW);
gtk_widget_path_iter_set_name(widgetPath, -1 , "UnityPanelWidget");
GtkStyleContext *context = gtk_style_context_new();
gtk_style_context_set_path(context, widgetPath);
gtk_style_context_add_class(context, "gnome-panel-menu-bar");
gtk_style_context_add_class(context, "unity-panel");
I used gtk_style_context_lookup_color and it gets the normal text color but not the text color in gnome-panel-menu-bar or unity-panel.
I tried using GtkCssProvider but it gets the generic style without the classes I added.
I'm using it in a Qt application to get a native GTK3 look and feel.
This code is working fine in a GTK application.
Thanks!

As far as I know you won't able to use the code above because Qt uses Gtk2 and not Gtk3. This means that you will get a core dump with a message similar to:
Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in
the same process is not supported
You might be able to do something hacky by accessing the Gtk 3 libs from a diff process, but is a hack.

Related

GTK+3 C gtk_label_set_use_markup for a GtkButton + CSS style

I'm porting a GTK+2 based application to GTK+3 on Ubuntu 16. I'm trying to set the markup for the label of a button but it seems something has been deprecated. Here is the original code:
gtk_label_set_use_markup(GTK_LABEL(GTK_BIN(button)->child), TRUE);
GCC now complains that GTK_BIN doesn't have a member 'child'. So is there another technique I can use to do this? I've really struggled to find any useful information on this.
Related to this...I'm also looking for a WORKING example of using CSS to setup widget styles for a GTK+3 app. The current app uses gtk_widget_override_background_color() which is now deprecated. It seems the only way to control color is with CSS but I can't seem to glue the pieces together yet. I need to setup different colors for different widgets.
After some searching and experimentation found a solution to part of the problem. This works to set the markup of a button label as long as the label is the only child of the button widget:
gtk_label_set_use_markup(GTK_LABEL( gtk_bin_get_child( GTK_BIN(button) ) ), TRUE);
I still have not found a way to dynamically control the background color of a label or button widget using styles.

Can I globally switch to native text rendering in Qt Quick Controls 2?

I would like to use native rendering for all the text in my application. For each Text, Label, etc. element I can do this
Text {
renderType: Text.NativeRendering
}
to trigger native rendering. I can also use the software renderer for the whole application:
QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
However due to some bugs with the software renderer and some performance issues, I would like to avoid that.
Is there a global switch to change the render type?
Since Qt 5.7, you can change the default Qt Quick text render type, but unfortunately only at build time. In order to change the default, you would have to rebuild libQt5Quick.so with QT_QUICK_DEFAULT_TEXT_RENDER_TYPE set to NativeRendering. For more details, see https://codereview.qt-project.org/#/c/121748/ .
If you have installed Qt using an installer from qt.io, install the source packages using the maintenance tool if you already haven't done so, navigate to qtdeclarative/src/quick, run qmake with the define, and build. Something along the lines:
cd path/to/Qt/Sources/5.8/qtdeclarative/src/quick
# NOTE: make sure to run qmake from the same/correct Qt installation
path/to/Qt/5.8/<spec>/qmake "DEFINES+=QT_QUICK_DEFAULT_TEXT_RENDER_TYPE=NativeRendering"
make -jN
If you have a self-built Qt installation, invoke make clean (or if you want to save time, just delete qquicktext*.o) before make to rebuild the library.
EDIT: Since Qt 5.10, it is also possible to specify the default text render type in C++ via QQuickWindow::setTextRenderType(). Just notice to set it before loading the QML content.
The environment variable QML_DISABLE_DISTANCEFIELD controls this.
If you put
qputenv("QML_DISABLE_DISTANCEFIELD", "1");
at the beginning of your main, you will get a nice and sharp text rendering everywhere.
Source: http://www.kdab.com/~thomas/stuff/distancefield.html
Add this line first in c++ main function : QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);

QFontDialog: get font color

On mac, the QFontDialog is mapped to a nice system font dialog.
It is possible to choose between every system fonts and it is also possible to choose the font colour and effects (underline, strikethrough etc...)
How can I get those attributes?
bool ok;
QFont font = QFontDialog::getFont(&ok, QFont("Helvetica", 10), this);
if (ok) {
// do something
}
From the Qt's docs it does not seem to be possible to get color property when using QFontDialog.
When using Mac you get the Mac native panel which also displays the color. It is recommended not to use the native panel on Mac:
Use Qt's standard font dialog on the Mac instead of Apple's native font panel. (Currently, the native dialog is never used, but this is likely to change in future Qt releases.)
Note, the above part (that it is likely to change in future release) was present since version qt4 on the docs...
You can use option property to use Qt's dialog: fontDialog->setOption(QFontDialog::DontUseNativeDialog);
For the underline, strikethrough and other font-related properties, you can access them through QFont API, e.g., QFont::underline().

How do "theme" icons work in Qt Creator Designer?

When I create the "Command link button" (QCommandLinkButton) it has relatively nice green arrow icon.
I would like to see what other nice icons can I choose. When I try to change the icon, [Theme] appears instead of path or some GUI selection dialog:
I also noticed the context menu:
When I click Set icon from theme, again expecting some GUI selection list, I get just a text field:
What I was imagining:
Where's the list of icons from which the green arrow was taken?
QIcon::fromTheme works under specific conditions.
If it can find it in the QIcon::themeSearchPaths() for the QIcon::themeName()
If the desired icon isn't there, Qt Designer won't be able to do any of the from theme, named icons.
But... if you check your target system for the theme search paths and set the theme name, you are more likely to have success.
Example
On linux, I wanted to get a plus and a minus icon.
I found list-add.png and list-remove.png fit the bill.
https://github.com/GNOME/adwaita-icon-theme/tree/master/Adwaita/16x16/actions
http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
I did a locate on my system and found these:
/usr/share/icons/gnome/16x16/actions/list-add.png
...
/usr/share/icons/gnome/32x32/actions/list-add.png
/usr/share/icons/gnome/scalable/actions/list-add.svg
/usr/share/icons/oxygen/16x16/actions/list-add.png
...
Forcing with fallback icon in QIcon::fromTheme
Find the icon on the filesystem:
ui->toolButton->setIcon(QIcon::fromTheme("list-add",
QIcon("/usr/share/icons/gnome/16x16/actions/list-add.png")));
Find the icon in the qt resource system...
Add the icon in a qrc file in your build, then reference it's path.
ui->toolButton->setIcon(QIcon::fromTheme("list-add",
QIcon(":/list-add.png")));
Overriding the current icon theme
qDebug() << "themeSearchPaths:" << QIcon::themeSearchPaths() << QIcon::themeName();
// themeSearchPaths: ("/usr/local/share/icons", "/usr/share/icons", ":/icons") "hicolor"
The default theme for the system, and for the target deployment machine, likely didn't have the icons in it I wanted... but the gnome or oxygen icon desktop theme installed would almost always have it...
QIcon::setThemeName("oxygen");
Note that you won't see the preview in Qt Designer necessarily because it doesn't set the theme until runtime of your code.
The gnome icon library has 1100+ icons in it. Here is one list:
https://gist.github.com/peteristhegreat/c0ca6e1a57e5d4b9cd0bb1d7b3be1d6a
This works as long as you know what themes are available on the target system.
The list from freedesktop.org has 286 icons listed.
Use icons included in Qt
Just like #peppe pointed out, Qt includes 70 standard icons, too.
widget->setIcon(widget->style()->standardIcon(QStyle::SP_BrowserReload));
http://doc.qt.io/qt-5/qstyle.html#StandardPixmap-enum
Conclusion
Using a stock library on your target system is probably the fastest. Using the Qt built-ins is fast to figure out and use, but is fairly limited. Using a resource file is probably the most robust method, and gives unlimited options on what icon to use.
Be sure to pick a standard icon pack, and think about licensing and attributions, and some other things like that.
And there is no shortage of icons available online:
https://www.quora.com/What-is-the-best-icon-library
https://www.google.com/search?q=open+source+icon+library
Hope that helps.
I don't think that's the function you want to use. The "theme" name there corresponds to the QIcon::fromTheme functionality, which uses icons named according to the FDO specification
http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
And they're not really supported on non-FDO platforms (Windows, Mac, ...) unless you deploy your own theme files.
Now some stock icons are shipped with Qt itself; I don't know how to set them from Designer, but from code you can use QStyle::standardIcon:
widget->setIcon(widget->style()->standardIcon(QStyle::SP_BrowserReload));
If the icon you need is not provided by Qt, you'll need to ship it. In that case the Resource System is a convenient way to bundle it alongside your executable.
Last, but not least, from a UX point of view you should consider using QToolButtons unless you're really building a Vista-like wizard.

Show standard warning icon in Qt4

I'm trying to display a "warning" icon next to a QLineEdit if it contains invalid data. I was trying to use QStyle::standardIcon(QStyle::SP_MessageBoxWarning) to get a standard pixmap and place it inside a QLabel, and in some cases this seems to work. When running Gnome the icon is displayed correctly, but when running under KDE no icon is shown. I assume that the warning icon is simply not included in the style used under KDE.
What is the preferred way to display a "standard" warning icon in Qt? Does there exist some list which shows which icons are included in every style? How can I get an icon from a style that I know includes the warning icon?
The last time I had a similar problem, I found this Qt labs discussion useful. It informed me that QIcon now (since 4.6 I believe) has a QIcon::fromTheme function that allows you to load an icon based on the Freedesktop.org Icon Naming Specification, and in addition provide a fallback icon to be used if the current theme does not have the icon in question.
What I did was then to include some very basic icons for use as fallback, and in general specify icons only by their Freedesktop names. This gave a theme-consistent look almost always, and the program still worked in cases where people were missing icons.
As for the warning icon, I'm guessing/hoping that every theme must have the one named "dialog-warning", and that it's what you're looking for.
I hope this helps.
Edit: Oh and, in case you don't know, it can be useful to look at for example the Tango icon set to get a rough idea of what the Freedesktop names correspond to (although it is of course theme-dependent).
Qt does bundle a number of images that are resources that you can use in your own code. These images are a superset of those available via standardIcon() You may want to verify that the particular image is included in the versions of Qt you're targeting.
The end result could look like the following:
QPixmap pixmap(":/trolltech/styles/commonstyle/images/up-128.png");
// use pixmap as needed
For anyone who wants to know how to do this in a Windows environment you can:
Create a qLabel in your custom class, and then in the constructor of that class create a QIcon with the style you want, convert it into a pixmap and use the QLabel::setPixmap() function to apply it to the one you created:
QIcon icon = style()->standardIcon(QStyle::SP_MessageBoxWarning); //or
//whatever icon you choose
QPixmap pixmap = icon.pixmap(QSize(60, 60));
ui->iconLabel->setPixmap(pixmap);
ui->iconLabel->setScaledContents(true); //you can set this to fill the
//dimensions of your qLabel if you wish.

Resources