Implementing Gedit style fullscreen HeaderBar - python

I am working on a Gtk+ 3 application that is likely to be used fullscreen most of the time, but needs to be switched between fullscreen and non-fullscreen, while maintaining access to the controls located in the header bar. The problem is, since the headerbar is part of the window decorations, it gets hidden when the window goes fullscreen.
My current kludge so ensure the controls are always available works like this:
Setup
create a Gtk.Window with vertical Gtk.Box as first child
create a custom Gtk.HeaderBar (w/ added full screen togglebutton)
set window's titlebar as my custom Gtk.HeaderBar
add all the window's content to the Gtk.Box
When window goes fullscreen
remove the Gtk.HeaderBar from the Gtk.Window titlebar
pack the Gtk.HeaderBar into the Gtk.Box (window's first child).
This results in the Gtk.HeaderBar being at the bottom of the window, so
re-position the Gtk.HeaderBar to the top of the Gtk.Box
When the window goes un-fullscreen
remove the Gtk.HeaderBar from the gtk.Box
set it as the Gtk.Window's titlebar
This results in the following Gtk-warning: gtk_window_set_titlebar() called on a realized window (who cares, just a warning)
This works, but it seems like very much of a hack, and more complicated than it should have to be. Am I missing something and there is a more straightforward approach?
I know several Gtk+ 3 based apps have the header bar behavior I am after (gedit for example), but I have not been able to determine how that is implemented. Any insight would be greatly appreciated.
Also, here is a GitHub gist with a full working example of my current hacky solution: https://gist.github.com/KurtJacobson/6b045b6fc38907a2f18c38f6de2929e3
I will accept answers in any (programming) language.

Related

Add side panel without resizing parent

I'm using PySide2 to write a gui (witout QtDesigner).
The mainwindow contains plots and some other widgets. Through a menu option I want to open a side panel widget. The way I want it to work is that the whole window simply grows to contain that new widget without changing the size of anything else in the main window. How can this be done?
Currently the widget is just added to the central layout with addWidget, I've also tried making it a QDockWidget but it is still resized (and anyway I would like to avoid the extra fluff that comes with having a DockWidget).
So I have
---------
|content|
---------
which should turn into
-------------
|new|content|
-------------
but currently I get
---------
|new|cnt|
---------
It's hard to do well on the "client" side of Qt; this would really belong within Qt itself. I have implemented a slightly more general variant of this a couple of years ago, and just to make it work well across Windows, Mac and KDE, the code ballooned to over a thousand lines to cover all the icky corner cases, with another thousand for the test harness. It was surprisingly hard to implement the tests - especially on X11, where there was no way around using native X APIs to verify intended behavior. I got rid of that monstrosity soon later - the effort was unnecessary.
You can have the side panel as a separate top-level frameless widget that moves itself so that its top-right corner is aligned with the top-left corner of the content window, and resizes itself vertically to match the vertical size of the content window. You can of course make it slightly shorter (vertically) while still center-aligning it vertically with the content window.
You'd want to capture the resize events of the content window to do this: the side panel should install itself as an event filter for the content window.
You'll want the side panel to be a Qt child of the content window, but you also need to make it a top-level window, i.e. set the Qt::Window flag on it, so that it becomes top-level and not a sub-widget of the content window.

Resizing an icon doesn't show on GUI

I am trying to make my GUI icon go bigger.
I tried this:
MainWindow.setWindowIcon(QtGui.QIcon('Logo1.png'))
MainWindow.setIconSize(QtCore.QSize(128,128))
When 'Logo1.png' is 128x128
When I change numbers SetIconSize line, like this:
MainWindow.setIconSize(QtCore.QSize(500,500))
It doesn't show on my GUI.
My questions are:
Does this happen because I need my logo to be smaller something like 28X28?
If I need a specific size, what size is it and how do I make my logo this size?
Even if I do need a specific size, why wont setIconSize change my icon size?
The iconSize property documentation of QMainWindow explains that:
[The] size of toolbar icons in this mainwindow.
As you can see, it has nothing to do with the windowIcon.
It is up to the underlying OS and its window manager to decide the size of the icon, whether its shown in the window decoration (tipically in the title bar), the task manager/window switcher or anything else, and you don't have any control over it through Qt.
The only "exception" is when drawing client-side windows: windows for which the whole decoration is drawn by the program (the title bar with its system buttons and icon, the frame around the window, etc.).
That is, though, something that is usually discouraged as it's hard to achieve without facing various difficulties (both with drawing and interaction); it also makes the window appearance inconsistent with the whole system and could also create issues with accessibility for visually impaired people.

Is it possible to create to create a Tkinter subwindow? [duplicate]

I wanted to ask if it is possible to draw a child window inside a parent window so that it will only be able to move inside the parent window and won't be able to move out of the parent window bounds.
If you mean having actual windows with title bar, menu, status bar etc. inside the parent window then the answer is:
No, Tcl/Tk and by extension Tkinter does not support this with its standard widgets.
There have been efforts in the past to implement widgets which emulate MDI as you can see on the TCL wiki, but most of them are over a decade old. You will probably have to implement it yourself or choose a different GUI toolkit if you really need to implement this kind of UI design.
If you do it yourself, you can use the Frame widget as the subwindow, and use place to put it in the containing window. Or, you can create it as an object on a canvas. You'll have to write all of the code to give the inner window borders and a title bar, and to manage moving it around, iconifying it, etc.

draw a window inside another

I wanted to ask if it is possible to draw a child window inside a parent window so that it will only be able to move inside the parent window and won't be able to move out of the parent window bounds.
If you mean having actual windows with title bar, menu, status bar etc. inside the parent window then the answer is:
No, Tcl/Tk and by extension Tkinter does not support this with its standard widgets.
There have been efforts in the past to implement widgets which emulate MDI as you can see on the TCL wiki, but most of them are over a decade old. You will probably have to implement it yourself or choose a different GUI toolkit if you really need to implement this kind of UI design.
If you do it yourself, you can use the Frame widget as the subwindow, and use place to put it in the containing window. Or, you can create it as an object on a canvas. You'll have to write all of the code to give the inner window borders and a title bar, and to manage moving it around, iconifying it, etc.

How do I get a windows border like this in Tkinter?

Is there any way to get a border like this in Tkinter? Notice how it lacks the buttons on the top right. Also I don't want this program to show in the task bar.
This is in windows 7, btw.
Tk (and thus, Tkinter) has a command for removing all window manager decoration. This command in tkinter is the "wm_overrideredirect" method of toplevel windows. Pass it a parameter of True to remove the window manager decorations. You can then draw whatever borders you want, usually by packing a canvas over the entire window and drawing on the canvas.
However, when I experiment with this on my Mac, the window appears properly but won't take focus. Perhaps this is a bug in Tkinter. I don't see the same problem with identical code in Tcl.
The WS_DLGFRAME window style should give you a window without a titlebar and WS_EX_TOOLWINDOW is normally also used for a window like this so it is not visible in the taskbar (Or with a hidden parent window like control panel dialogs before Vista) You can figure out the exact window styles with a tool like Spy++ (Visual Studio) or WinSpy++

Categories

Resources