How does Qt select a default style? - c++

In a Qt GUI application, QApplication::style()->objectName() will return the current style, for example "windowsvista".
How/where does it choose this default style, and what information does it use to decide?

Qt comes with builtin styles, these are (on my 5.9.2):
Windows
WindowsXP
WindowsVista
Android
Fusion
Macintosh
each one having its own class, derived from QStyle.
To see which ones are available (it depends on Qt build configuration):
const auto & styles = QStyleFactory::keys();
for(const auto & s : styles)
{
qDebug() << s;
}
Custom plugins (i.e. libraries in the QTDIR/plugins/styles directory) would be shown as well, if present.
How the default style is chosen?
Default style is searched in QApplication method style(), in qapplication.cpp file, in this order:
The style override, if set by the environment variable QT_STYLE_OVERRIDE (this is set in QApplicationPrivate::process_cmdline());
The style returned by QApplicationPrivate::desktopStyleKey() (this method loads a list of styles from the current platform theme and select the first name from this list that is present in the QStyleFactory::keys() list);
The first item in QStyleFactory::keys() list.
If a style could not be determined, the function will assert
Q_ASSERT(!"No styles available!");

In the documentation:
Qt contains a set of QStyle subclasses that emulate the styles of the
different platforms supported by Qt (QWindowsStyle, QMacStyle etc.).
You can set the style by using a key: windowsvista for example, fusion, macintosh, etc. When using any key, the style returned will be a subclass of QStyle. Depending on the platform you're using, you will have access to a certain number of keys.
How/where does it choose this default style
It is done in the QStyleFactory source file. You can also take a look a the QStyle source file to get a hang of what's going on.
what information does it use to decide
The default style is platform dependent, and then you can choose any style among the keys at your disposition on this platform.

Related

How to load multiple font of same familiy

I am writing an application using the Qt framework. In the display, I have to show multiple information, but using different types of font of the same family, Montserrat.
What I have done so far to load the fonts is:
int ultralightid = QFontDatabase::addApplicationFont(":/Montserrat_UltraLight.tff");
QString UltraFont= QFontDatabase::applicationFontFamilies(ultralightid ).at(0);
QFont font1(UltraFont,QFont::Normal);
font1.setPixelSize(50);
int lightid = QFontDatabase::addApplicationFont(":/Montserrat_Light.tff");
QString LightFont= QFontDatabase::applicationFontFamilies(lightid).at(0);
QFont font2(LightFont,QFont::Normal);
font2.setPixelSize(150);
label1->setFont(font1);
label2->setFont(font2);
label1->setText("bla bla");
label2->setText("bla bla");
The font sizes are correct, but the font itself it is not. From what I have noticed (trying with Hairline_Montserrat,Light_Montserrat,UltraLight_Montserrat), it is as if the fonts have a sort of priority. If I declare them all, all the fonts are the Light one, if I comment that font type, all of them are Hairline one, otherwise (last priority) the labels use the ultralight font.
I have tried adding other font type (from other families) and in that case my code works correctly.
If I use
qDebug()<<QFontDatabase::applicationFontFamilies(ultralightid);
qDebug()<<QFontDatabase::applicationFontFamilies(lightid);
both of them print the family "Montserrat".
I use the qrc file and the AUTORCC flag in the CMAKE (it should be similar using qmake) and all the file are uploaded correctly.
Do you know if there is another way to add fonts of the same family? Or is there something I am doing wrong?
Here are the fonts:
https://www.onlinewebfonts.com/download/9d31c906a6cc6064bbe7d33d51058317 light
https://it.allfont.net/download/montserrat-light/ ultralight
This is an old question but I was just struggling with exactly the same problem when trying to load normal, bold, ... versions of a font family in Qt.
I solved the problem (although in a somewhat hacky way) by simply giving each of the ttf files a different family name. I used Typograf, simply open the font, right click to open properties and then click rename. There are probably many other tools that do this too.
You don't need to manage font files from one family separatelly.
I suggest this solution:
Create a folder with all ttf's of the same family.
Load all files from the folder via id = QFontDatabase.addApplicationFont(path)
Collect all font families from these files via QFontDatabase.applicationFontFamilies(id)
Check if only one and desired family is loaded, and the family name is exactly the same as requested, or warn the user about these errors.
Create font object font = QFont(family)
Then for example, font.setItalic(True). If Italic version of family is loaded, it will be used, otherwise it will be created from Regular by QT.

Arbitrary Inspection of Qt Stylesheet

I have several Qt stylesheets that look something like this:
MyClass
{
my_color: #abcdef;
}
However, I recently moved MyClass into a new namespace, ns, which means that its corresponding qss classname is now "ns--MyClass", not just "MyClass". As a result, all my stylesheets are now invalid. Unfortunately, they aren't all under my control, so I cannot edit them manually.
So my question is: how can I configure ns::MyClass to use all the same style settings of MyClass?
Obviously, Qt has to parse the style sheet at some point. So if I could access the parsed style sheet and extract just the portions that affect MyClass, I should be able to add those portions into ns::MyClass via setStyle() or setStyleSheet(). But I cannot find a way to do this.
I am targeting Qt 4.8.
You'll need to patch Qt to add two methods to QApplication:
void setClassSubstitutions(const QMap<QString, QString> &);
QMap<QString, QString> classSubstitutions() const;
The substitutions would be held in the application's PIMPL, and you'd need to have the stylesheet mechanism use them. The entirety of the patch needed for Qt would be probably two dozen lines (or so I hope).

NSStatusItem setTitle is ignored on Yosemite

I've been working on a new feature for Mac support in Qt. Basically, it's about adding a NSStatusItem::title() support. Since Qt is a C++ framework, I am working in scope of ObjC-binding (corresponding method is declared in C++ header and defined in .mm source file).
void QCocoaSystemTrayIcon::updateTitle(const QString &title)
{
NSString *nstitle = title.toNSString();
[trayItem setTitle: nstitle];
}
Note: in the code above, toNSString() creates & releases a proper NSString* in place.
Interesting, if you replace actual setting line with
[[trayItem view] setToolTip: nsstring];
tool tip, in fact, is being changed. It proves that trayItem and nsstring are proper objects.
I am running IIRC latest OS X Yosemite 10.10.1
Almost all NSStatusItem methods are deprecated in Yosemite because of the new vibrancy features. Nice description here, NSStatusItem change image for dark tint
The fact that [trayItem view] returns a valid object suggests that you or Qt is setting a custom view.
Once you set a custom view on a status item, setting the title has no effect. (This was true even before these methods were deprecated).
A standard status item (no set custom view) can have its image and title set and have that be forwarded onto the implicitly created button. This was made more explicit/obvious in 10.10 in that those status item properties were deprecated, and you set the button's properties directly.

Setting wxTE_PASSWORD later

I created two wxTextCtrl. One for log in (loginTxt) and another for password (pwdTxt) and both have readable default message.
I also installed wxEVT_LEFT_DOWN event so that when user click on either loginTxt or pwdTxt the default message will be set to empty string
Is it possible to set wxTE_PASSWORD style to the pwdTxt later? If it's possible, how can I do that?
I read wx.chm and it say,
"Note that alignment styles (wxTE_LEFT, wxTE_CENTRE and wxTE_RIGHT) can be changed dynamically after control creation on wxMSW and wxGTK. wxTE_READONLY, wxTE_PASSWORD and wrapping styles can be dynamically changed under wxGTK but not wxMSW. The other styles can be only set during control creation.".
I am writing my application on MS Windows with wxWidgets 2.9.3
You cannot change it later on Windows, since Microsoft's control does not support that. If you really need to, I suggest creating 2 different controls and show/hide the appropriate one.
Windows-only solution, probably will be useful:
void Sample::OnBUTTONClick( wxCommandEvent& event )
{
#if defined(__WXMSW__)
HWND hWnd = (HWND)m_Text->GetHandle();
SendMessage(hWnd, EM_SETPASSWORDCHAR, 0x25cf, 0); // 0x25cf is ● character
m_Text->Update();
#endif
}

Restoring default GUI QStyle on Windows 7 OS

I'm writing a GUI application using Qt 4.7 on Windows 7 Ultimate 32 bit. I'd like to let users change the GUI style from main menu. Several QStyles (QCDEStyle, QWindowsStyle, QCleanlooksStyle etc) can be selected from the menu and I'm using QApplication::setStyle() to set the new style.
I'd like to have an option to return back to the default style for Windows 7. By default style, what I mean is to use the style returned by QApplication::style() before any style is set explicitly using QApplication::setStyle(). Following is the attempt that will not work:
QStyle *default_style;
// During initialization of QMainWindow
default_style = QApplication::style();
// When default style is chosen from main menu
QApplication::setStyle(default_style);
The above will not work because QApplication::setStyle() takes ownership of the object and deletes previous QStyle*.
How can I change QApplication style to the default one? Thanks.
After a bit of sourcediving, it turns out styles have their object names set to the style name, so you can say:
QString defaultStyle = this->style()->objectName();
and later
qApp->setStyle(defaultStyle);