Ubuntu ignores PyQt4 flags - pyqt

I wanna have a CustomDialog, which'll have minimize button and close button (no maximize)
So, what I do
from PyQt4 import QtGui
class CustomDialog(QtGui.QDialog):
def __init__(self):
super(WinDialog, self).__init__(None,
QtCore.Qt.WindowMinimizeButtonHint |\
QtCore.Qt.WindowCloseButtonHint|)
In Windows It works as expected - in title bar go minimize button, then disabled maximize button and then close button
In Ubuntu I see no changes at all - close button next to maximize button. No minimize - CustomDialog behaves like it still is QDialog.
I don't know If it's Ubuntu "bug" or "PyQt" - for now I'm just confused.

From the documentation
Note that the X11 version of Qt may not be able to deliver all combinations of style flags on all systems. This is because on X11, Qt can only ask the window manager, and the window manager can override the application's settings. On Windows, Qt can set whatever flags you want.
So it is likely the fault of your windows manager in ubuntu.
Note that you might want to try updating the existing window flags, just to ensure you haven't overridden an important default (your current method of setting the window flags just sets the ones specified). You can instead do this to preserve the default window flags, but modify the ones you care about:
def __init__(self):
super(WinDialog, self).__init__(None)
windowFlags = self.windowFlags()
windowFlags &= ~Qt.WindowMaximizeButtonHint # remove maximise button
windowFlags &= ~Qt.WindowMinMaxButtonsHint # remove min/max combo
windowFlags &= ~Qt.WindowContextHelpButtonHint # remove help button
windowFlags |= Qt.WindowMinimizeButtonHint # Add minimize button
self.setWindowFlags(windowFlags)
Note that flags &= ~flag removes a flag. flags |= flag adds a flag.

Related

PYQT change clearButton in QLineEdit (w/wht Qt Designer)

Since I updated python from 3.8 to 3.10 (with Linux Ubuntu 22.04), clear button in QlineEdit widget has become an ugly red cross. It was before a nice dark kind of rectangular button with a small cross inside.
I wish I could switch back to the previous clear button without having to create a custom button, because the red cross is kind of disturbing as it seems to indicate an error in what you write in the QLineEdit widget.
Is there a way to do that in Qt Designer or programmatically?
It seems a bit unlikely that just updating Python would affect the icon.
The update probably involved other packages along with it (or they need rebuilding, they were uninstalled due to incompatibilities, etc), so I'd suggest to check that first.
In any case, you can set the icon using a specific stylesheet you could set for the top level window or even the application, so that it will be used for any QLineEdit with the clear button enabled:
QLineEdit > QToolButton {
qproperty-icon: url(/path/to/icon.png);
}
Note that this will override all icons of QLineEdit, including those used for custom actions, so in that case you must explicitly set the object name of the button and use the proper selector in the QSS:
# this assumes that the clearButtonEnabled property is already set,
# otherwise it will crash
lineEdit.findChild(QToolButton).setObjectName('clearButton')
lineEdit.setStyleSheet('''
QLineEdit > QToolButton#clearButton {
qproperty-icon: url(/path/to/icon.png);
}
''')
Also, see this related answer for other alternatives.

PYQT5 Simulating Window Menu MacOS

I'm attempting to simulate the native MacOS "Window" menu in PYQT5. I am able to cycle through open windows via my menu and indicate the active window by setting its checked state to True.
I would like to also simulate the MacOS HID icon assigned when a window is minimized like this:
However, the closest I have been able to come is with a QIcon, which isn't quite right (the icon isn't quite right either, but I can live with that).
bring = self.view_menu.addAction('&Bring to Front', self.foo)
bring.setIcon(QtGui.QIcon("diamond.png"))
Is it possible to have the QIcon displayed in the left menu column (aligned with the checkmark) or otherwise display a diamond for an action item like MacOS? I didn't see any parms for the QIcon class that appeared to do this.

How to make an overlay which capture no events

I would like to draw some sort of window on top of all the other windows. For example, to display some debugging infos (like conky) or things like a timer.
The main thing is that I would like to able to continue using the other windows while using it (the events go through transparently).
I've tried doing it with pygtk, pyqt and others but can't find a way to make it a real overlay with no event capture.
Is there some low-level x11 solution?
I think the Composite-extension-approach will not work when a compositing manager is running (and thus Composite's overlay window is already used).
Since you explicitly mention "no event capture":
The SHAPE extension allows to set some different shapes for a window. Version 1.1 of this extension added the "input" shape. Just setting this to an empty region should pretty much do what you want.
Some concrete example of exactly what I think you ask for can be found in Conky's source code: http://sources.debian.net/src/conky/1.10.3-1/src/x11.cc/?hl=769#L764-L781
Edit: Since you said that you didn't find anything in Gtk (well, PyGtk), here is the function that you need in Gtk: https://developer.gnome.org/gdk3/stable/gdk3-Windows.html#gdk-window-input-shape-combine-region
You might need Composite extension + GetOverlayWindow request:
Version 0.3 of the protocol adds the Composite Overlay Window, which
provides compositing managers with a surface on which to draw without
interference. This window is always above normal windows and is always
below the screen saver window. It is an InputOutput window whose width
and height are the screen dimensions. Its visual is the root visual
and its border width is zero. Attempts to redirect it using the
composite extension are ignored. This window does not appear in the
reply of the QueryTree request. It is also an override redirect
window. These last two features make it invisible to window managers
and other X11 clients. The only way to access the XID of this window
is via the CompositeGetOverlayWindow request. Initially, the Composite
Overlay Window is unmapped.
CompositeGetOverlayWindow returns the XID of the Composite Overlay
Window. If the window has not yet been mapped, it is mapped by this
request. When all clients who have called this request have terminated
their X11 connections the window is unmapped.
Composite managers may render directly to the Composite Overlay
Window, or they may reparent other windows to be children of this
window and render to these. Multiple clients may render to the
Composite Overlay Window, create child windows of it, reshape it, and
redefine its input region, but the specific arbitration rules followed
by these clients is not defined by this specification; these policies
should be defined by the clients themselves.
C api : XCompositeGetOverlayWindow
PyGTK Solution:
I think the composite and shapes X extensions are sufficiently ubiquitous and shall assume here that they are active on your system. Here's PyGtk code for this:
# avoid title bar and standard window minimize, maximize, close buttons
win.set_decorated(False)
# make the window stick above all others (super button will still override it in the z-order, which is fine)
win.set_keep_above(True)
# make events pass through
region = cairo.Region(cairo.RectangleInt(0, 0, 0, 0))
my_window.input_shape_combine_region(region)
win.show_all()
# set the entire window to be semi-transparent, if we like
win.set_opacity(0.2)
Basically what this does is tell Gtk that other than pixel (0,0) the entire window my_window should not be considered part of itself in terms of event propagation. That in turn, according to my current understanding means that when the pointer moves and clicks, the events go to the underlying window under the pointer position, as if my_window was not there.
Caveat:
This does allow your overlay window being the focus window (due to user-solicited window switching or just because it pops up and gets the focus when your application starts). Which means that for example, keyboard events will still undesirably go to it up until the user has clicked through it to make it lose focus in favor of whatever window is under the cursor. I would likely use the approach described here to iron out this aspect.
If there's a different and proper approach for making a portion of the screen "display stuff but not receive events", without building an oddball window like above over it, I'm happy to learn about it.
I assume that one's particular desktop environment (gnome, unity, etc. on linux) may interfere with this solution depending on version and configuration, on some occasions.

Different QWidget behaviour on Windows and Linux

QWidget is created after some time in my app. I start my app. Then I use internet browser. On Linux my new widget appeares over my browser, but on Windows - not. Widget has parent widget. How to fix it on Linux?
both parent and my widget have only setFocusPolicy(Qt::StrongFocus); The Linux OS is Xubuntu. And one difference in parent class:
#if defined(Q_WS_X11)
setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
#else
setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
#endif
I believe Windows prevents other programs from stealing the focus while some other OS may not enforce that.
When you create your widget, you should set the window state before making it visible.
For instance
QWidget* lateWidget = new QWidget(this); // or add to layout or whatever
lateWidget->setWindowState(this->windowState());
lateWidget->show();
Edit:
From the docs :
A widget that happens to be obscured by other windows on the screen is
considered to be visible
Which means that if you open the browser on top of parent then lateWidget->show() will ask to the window system to be activated.lateWidget which then pop on top and gain user mouse and keyboard focus.
before showing lateWidget a quick fix is to use
lateWidget->setAttribute(Qt::WA_ShowWithoutActivating);

Fvwm Style For the windows

I currently use FPClickToFocus, FPClickDecorToFocus, FPClickIconToFocus, FPGrabFocusTransient for the window style. But the Problem is the Window loses Focus when mouse leave it and give the focus to the window it is in;
So which Style(s) give the normal fill and look in this specific matter; like other WMs openbox, gnome ... (i.e click in the window or on its titlebar; gives it focus and bring it on top)
Using this below Style(look down) only changes and brings window to the front but the Focus (the window that action happens in i.e i can type in) doesn't change.
It means I change a window but my cursor is still in my geany and i am typing a web-site URL in geany while the firefox is in front and nothing happening in its addressbar For Example.
#-----------------------------------------------------------------------
# The focus policy. Once you are used to clicking *inside* windows to
# raise them you will not want to lose this feature.
#-----------------------------------------------------------------------
Style * ClickToFocus
Style * MouseFocusClickRaises

Resources