QtWidgets: Is it possible to apply flat main window style (Visual Studio-like) via QSS?



  • I want my Qt Widgets app look modern and not have this useless thick window frame (but still have min / max / close buttons, preferably). I like the VS style: http://i.imgur.com/nyTwOQE.jpg

    Is it doable with QSS?


  • Moderators

    @Violet-Giraffe said:

    Is it doable

    Yes

    with CSS?

    The client area - yes.
    The frame - no, not with QSS. It is a non-client area handled by the window manager and, as such, requires platform dependent code.
    This is a semi-regular question. Search for custom window frame or non-client painting and you'll find some hints of how complex task that is and how to go about it.



  • Check this out



  • @Chris-Kawa said:

    you'll find some hints of how complex task that is

    Thanks, that's pretty much all I needed to know to discard this idea, I guess.
    I could make the window frameless and draw the title and the minimize / maximize / close buttons in the client area, though, couldn't I?


  • Moderators

    I could make the window frameless and draw the title and the minimize / maximize / close buttons in the client area, though, couldn't I?

    You could. That's the first idea everyone has ;)

    But then they realize that resizing and moving the window stops to work. So they implement that with mouse events. But then they realize that cursor doesn't change at the borders. So they hack around that too.
    But then, on Windows, because the frameless window removes some native window flags (namely WS_CAPTION, WS_THICKFRAME, WS_MAXIMIZEBOX, WS_MINIMIZEBOX), the aero features stopped working (e.g. aero snap). So they revert to native events hacks which work like 70% of the time. But then they realize that maximizing starts to have artifacts (e.g. edges bleed to other monitors in multi-display systems). So then they invent horrible resizing hacks for that. But then they realize the thumbnail preview in the taskbar includes unclickable close button they drew themselves. At which point they decide to compromise and leave some stuff unhandled/handled wrong. So they end up with semi-working but not really solution that falls down for example as soon as someone switches to high contrast window theme or changes system dpi setting...

    I hope you now see that the "how complex task that is" is not something I just made up :)



  • Gee, I didn't realize borderless windows can't be resized.
    Thanks for the detailed explanation. I definitely don't need any of that trouble.



  • Has no one ever created an open-source, or at least free, fully functional frameless window implementation (perhaps, for specific operating system(s) only)? It must be a common task! I don't necessarily mean just a style, could be a custom QmainWindow / QWidget.

    One application that comes to mind is Blizzard's Battle.net game client (pretty much the same thing as Steam and Origin). It has highly customized flat UI (screenshot: http://i.computer-bild.de/imgs/5/6/3/3/1/8/1/Screenshot-1-Battle-net-App-745x447-3915f5e4f4e03187.jpg) and it uses Qt. Btw, Origin also uses Qt and has custom title bar: http://img46.imageshack.us/img46/2822/0gc6.jpg


  • Moderators

    Custom look is no big deal. As you said yourself a frameless window with a couple of mouse events can do the trick.
    The real problem, as I mentioned earlier, is the true native behavior on given platform, which is often non-trivial.

    Notice that at least Origin client has exactly the half-baked solution I talked about - completely ignores OS integration, i.e. Aero features like snap or Win + arrows shortcuts don't work and maximizing on multiple screens has issues too. It also renders frame as part of taskbar thumbnail, which apps shouldn't do. As a result it doesn't feel native at all.
    Some of the issues can be avoided with a fixed size window (I think the Blizard thingie does that?), but it doesn't fit with all apps .

    I've actually seen many many apps doing it wrong one way or another and really a handful doing it right.
    Even Visual Studio has issues - when it becomes heavy loaded a micro-freezes occur at which time the OS tries to handle it by drawing native frame over the frozen app, which looks terrible.

    Not to say it's impossible. It's just really really hard to nail all the details and I guess nobody (to my knowledge) cared enough to perfect it and release for free.
    I have personally tackled it many times and have a couple of "almost always working" solutions. They are just so hacky and ugly (code wise) I wouldn't feel comfortable sharing them with others. I guess others that did this feel similarly, although if you look through this forum you'll find code of such failed, or not entirely working attempts.



  • I bet if it was on Github and received some advertisement, we (the community) would more or less polish it.
    Good catch on the Origin client failures. Battle.net, of course, also draws the whole window in the thumbnail, but it does support snap to screen edges (incl. Win + arrows). WinAPI code?..



  • This looks decent: https://github.com/deimos1877/BorderlessWindow
    The code, though... quite complicated, and Windows-only.


  • Moderators

    This looks decent

    Sorta does the job but I don't really like it. Seems heavy and intrusive - two event loops, stylesheets, images, resources and external library needed.
    Also the API needs a lot of polishing to be more in line with Qt - for example why would a widget take application pointer and store it? I also really dislike that the header bleeds "windows.h" into the app and the main class exposes native types (e.g. styles, HBRUSH, HWND, WPARAM etc.) to the user. This needs to be hidden away behind an API that has Windows specific stuff ifdeffed.

    But thumbs up for the effort. It might be a starting point, though I'm not convinced about the method. I'd personally go for handling native events inside the widget instead of embedding it in native window via QWinWidget. I'd like my main window to be a QWidget too.

    Btw. It's an uphill battle. In about two weeks Windows 10 comes out and with sandboxed WindowsRuntime apps that can be now windowed this doesn't even cover one platform entirely, let alone linux, macos or others.



  • Well, personally, I'm not interested in WinRT, only the good old x86 Win NT. I don't have a single WinRT-compatible application.


  • Moderators

    I'm not talking about WinRT - the "tablet OS". I'm talking about the Windows Runtime - the successor of WinAPI (great job at not confusing users with ambiguous names Microsoft :P). The stuff that used to be called "metro apps". It's pushing to be the prevailing API for writing windows apps, especially since they are back to windows in Windows 10 instead of being fullscreen in Windows 8. If you're not interested in that now, you will be (or will have to be) in at most couple of months/years.



  • Got it. But I doubt good old WinAPI / WPF applications will stop working any time soon.



  • @Chris-Kawa I just have to say this is hilarious and spot on. I did this same thing in wxWidgets a couple years ago and this was my experience verbatim. In the end I went on to use the same basic technique that is described here: https://github.com/deimos1877/BorderlessWindow. Thanks for making me feel less stupid.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.