Restoring default GUI QStyle on Windows 7 OS - c++

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);

Related

How does Qt select a default style?

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.

Use a system icon in the setIcon method of QWidget

I would like cross-platform a way to get a system icon, for example the folder icon in the setIcon method of QWidget. Something like this:
QWidget *myWidget = new QWidget;
myWidget->setIcon(/*something to get a system icon*/);
Is this possible? If it is, how to do it?
Use QFileIconProvider::icon(IconType) to get an icon of a particular kind, from a small selection of types.
In your particular case, you'd want icon(QFileIconProvider::Folder).
Use QFileIconProvider::icon(const QFileInfo &) to get an icon for a particular directory entry.
Use QIcon::fromTheme(const QString &, const QIcon & = QIcon()) to get a theme icon on Linux/X11.
I think you're looking for QIcon::fromTheme method.
Example:
QIcon undoicon = QIcon::fromTheme("edit-undo");
Note: By default, only X11 will support themed icons. In order to use themed icons on Mac and Windows, you will have to bundle a compliant theme in one of your themeSearchPaths() and set the appropriate themeName().
For linux/X11, maybe you are looking for QMimeDatabase::mimeTypesForFileName and QIcon::fromTheme.
Refer to https://stackoverflow.com/a/45739529/5785726 for a example

QWidget transparency goes away when parent set

I want to have "flying" info above my interface (like informationnal text).
I have subclassed QWidget, set the FramelessWindowHint and TranslucentBackground flags.
So I create it with my interface's widget as ctor parameter, and style (style is in a ressource QSS file and set to qApp in main) does apply to my custom widget except for background (I can put a borderbut no background-color).
But when I make my custom widget it's own parent (I leave ctor parameters empty), then I can have my background changed.
I used this technique with the exact same flyingwidget class in another project and it worked just fine. QGLWidget may be in cause (creating widget before or after QGLWidget are created causes style to be applied or not).
here's the code where I create my widget.
Form_coupeHighlighterInfo *highlightCoupeInfo = new Form_coupeHighlighterInfo(this); //ctor parameter that changes
highlightCoupeInfo->setObjectName(QStringLiteral("highlightCoupeInfo"));
highlightCoupeInfo->attachToRight();
highlightCoupeInfo->setFixedWidth(400);
highlightCoupeInfo->setFixedHeight(400);
highlightCoupeInfo->setRelativePos(QPoint(-10, 0));
connect(this, SIGNAL(alignToInterface(QPointF&)), highlightCoupeInfo, SLOT(alignToInterface(QPointF&)));
I must add that background property doesn't work like the others but I don't get what the hell is going on with him, QSS looks like magic to me on a lot of points.
I use Qt 5.2.1 / msvc2012opengl / windows 7

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
}

Motif main window w/o system menu, minimize and maximize boxes how? (C++)

How do I create a Motif main window that doesn't have a system menu, minimize and maximize boxes? I just cannot find out how by googling and reading docs and tutorials. I believe that it should be possible with some additional parameters for XtVaCreateManagedWindow, but which?
I have tried several variants of XtVaSetValues (topWid, XmNmwmDecorations, ...) but none worked. Instead I get an error message that I need to use a vendor shell for this. Most widget types aren't derived from vendor shells however, and when I e.g. try to use a dialog shell and put a scrollable text widget inside of it, then then text widget seems to control the dialog.
Apparently it's not (easily) possible to get rid of the window (system) menu, but it seems to be possible to disable window menu items with some code like this:
int i;
XtVaGetValues (widget, XmNmwmFunctions, &i);
i &= ~(MWM_FUNC_ALL | MWM_FUNC_MINIMIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE);
XtVaSetValues (widget, XmNmwmFunctions, i);
which removes the related window decoration too and apparently even works for non vendor shell widgets.
There should also be the possibility to remove the decorations (i.e. make them invisible). However, please note that these "system menu" decorations belong to the Window Manager, not your Motif program itself. It is up to the Window Manager to handle your requests or disregard them--you might get vendor-specific behavior with any MWM resources.
Anyway, here's the code sample to try out:
int decors; //bit-mask of flags defining the decorations, from Xm/MwmUtil.h
XtVaGetValues(dlg, XmNmwmDecorations, &decors, NULL);
decors &= ~MWM_DECOR_MENU;
decors &= ~MWM_DECOR_MAXIMIZE;
decors &= ~MWM_DECOR_MINIMIZE;
XtVaSetValues(dlg, XmNmwmDecorations, decors, NULL);
If you intend to run your application from Mwm, you can achieve the desired behavior by setting (e.g. via XtVaAppInitialize()) the following X11 resources:
! Title bar buttons
Mwm*YourApplicationClassHere.clientDecoration: -minimize -maximize
! Window menu functions
Mwm*YourApplicationClassHere.clientFunctions: -minimize -maximize
These resources are explained in more detail here and here.
Speaking of window menu, this one depends on a specific window manager in use. Mwm, for instance, allows the client to set the menu name using Mwm*YourApplicationClassHere.windowMenu resource, the menu itself must be defined in either ${HOME}/.mwmrc or global mwmrc, or XmNmwmMenu resource of VendorShell. The resulting custom window menu is exposed as a _MOTIF_WM_MENU atom, which seems to be ignored by modern window managers.
Sample mwmrc menu definitions may look like this
Menu CustomMenu0
{
Restore _R Alt<Key>F5 f.restore
Move _M Alt<Key>F7 f.move
Size _S Alt<Key>F8 f.resize
Minimize _n Alt<Key>F9 f.minimize
Maximize _x Alt<Key>F10 f.maximize
Lower _L Alt<Key>F3 f.lower
no-label f.separator
Pass\ Keys _K f.pass_keys
no-label f.separator
Close _C Alt<Key>F4 f.kill
}
Menu CustomMenu1
{
Your\ Application\ Name\ Here f.title
no-label f.separator
Close _C Alt<Key>F4 f.kill
}
(see the function descriptions). Custom menu items can be added using f.send_msg (examples here and here).
I'm pretty sure all of the above also applies to Dtwm (CDE).