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.
Related
I'm looking for a way to make a toplevel window transparent for mouse clicks and keyboard events. So basically it has to be only visible for the user, not interfere with what else happens on the desktop. (will be transparent) I looked at various options like setting a mask, but that also makes the window disappear where the mask is set. So what I need is a mask, only for user actions, not for visibility.
I got this to work in PyGtk using input_shape_combine_mask()
which accesses x11 shape extensions. I looked for a similar function in PyQt but couldn't find it. In other posts I find it has been done in PyQt under windows. But x11 I couldn't find yet. Any suggestions?
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.
I am trying to create a dockable window in Qt (it sits taking 4px width at the edge of the screen, always on top and it slides out when you hover it). I have to use WindowFlag BypassX11WindowManager (in order to hide taskbar hint, disable moving/resizing/etc. from window manager). I use these flags:
Qt::FramelessWindowHint
Qt::CustomizeWindowHint
Qt::X11BypassWindowManagerHint
Qt::WindowStaysOnTopHint
When I need my dock to be activated, I use the activateWindow() method. However, I have no idea, how to deactivate it.
Is there a way I can force my window deactivate? Now I can do it only by clicking another window and then return to the one that was active before revealing dock.
You should be able to use ->hide() to simply hide it if you don't want it to appear at certain points.
I assume, by the way, you know there is QDockWidget/ class that may help you as well. It's unclear from the above if you're using it or not.
I'm having a bit of trouble with custom action buttons in the honeycomb+ action bar. I'm adding a menu item that uses a custom layout (using the android:actionLayout attribute). The reason for the custom layout is that I want a button that has two lines of text that can be updated dynamically.
However, I still want this action button to operate like the other standard buttons. By this I mean that the background fades in when the button is selected, and fades out again if it is unselected, all in the style of the platform (the colour seems to differ between different platforms/devices - I've seen both grey and blue versions)
I've tried using the action button style for the custom layout:
style="#android:style/Widget.ActionButton"
and I've tried setting the background for the custom layout to:
android:background="?android:attr/actionBarItemBackground"
but to no avail, and I'm kind of trying things fairly randomly as I can't find any documentation on how to do this (or if indeed it is even possible).
I know I can approximate this behaviour myself by setting the background, but it would be nice if I could just set the item to behave like a normal action button in terms of how it appears when the user interacts with it.
Anyone have any ideas?
Thanks in advance!
Ah, sorry to answer my own question but I have just stumbled upon a way to do this. I was halfway there - you need your custom layout's style to inherit from ActionButton:
#android:style/Widget.ActionButton
but then you also need to make the layout clickable:
android:clickable="true"
for it to work. Using both of these makes the custom action buttons look just like the regular ones when you press them.
Hopefully that'll help someone trying to do this!
I'm trying to figure out a way of using Qt Designer to make a dynamic GUI. For example, let's say I have a main window with a horizontal layout. I have a push button on one side and an empty area on the other. When I click the button the empty area will be filled with a widget that I've made in Qt Designer. When the button is pressed again the widget will be replaced with another widget that I've made in Qt Designer. Would I have to go about making all my widgets, to fill the empty area, custom widgets?
I've tried setting the parent to the empty are, but on the second change I get this
QLayout: Attempting to add QLayout "" to QWidget "t2", which already has a layout
So then I tried deleting the layout but still see the old widget underneath the new one and the layout is now messed up.
help please
Never mind, figured it out. Simple really. Use QStackedWidget and as for the UIs made in Qt Designer wrap that in a class that inherits from QWidget.