0

I need a window with the following properties:

  • It should be always on top.
  • Able to receive mouse events (movements and clicks).
  • Does not steal keyboard focus when clicked on.

Since a solution through Qt does not exist, I know that we have to use the Win32 API for the Windows platform. And I have to use this call:
SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_NOACTIVATE)
But how can I implement this in my Python code?

Nicely explained here: qt_forum.

My code:

class Ui_self(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(150, 200)
        self.secret_button = QtWidgets.QPushButton(self) 
        self.secret_button.setText("# tag")
        elf.setWindowFlags(Qt.WindowStaysOnTopHint) 
        elf.setWindowFlags(Qt.FramelessWindowHint)
        self.secret_button.setFocusPolicy(Qt.NoFocus)
        self.setFocusPolicy(Qt.NoFocus)
        self.setAttribute(Qt.WA_ShowWithoutActivating)
           
if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = Ui_self()
    ex.show()
    sys.exit(app.exec()) 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    Please *stop* creating multiple posts all around the same topic, it's considered noise and an abuse of the system. If you want to provide more details or show your progress, use the [edit] link instead. Please consider that this kind of behavior often leads to suspension. Also, if some comment or reference is not clear to you, then please answer to that comment instead of creating again new questions. – musicamante Jul 06 '21 at 20:45
  • @eyllanesc I've noticed the post only when you already had answered, and I wasn't really sure about what action should I had to take (and I'm also on mobile, so my research was limited). I did raise a flag, btw. – musicamante Jul 06 '21 at 21:05
  • @musicamante What should be done is to mark as a duplicate as you did (although I prefer to close the post with less information), the flag is unnecessary and possibly it will be rejected since this type of problem is handled by the community and not the moderators – eyllanesc Jul 06 '21 at 21:12
  • This isn't going to have the effect you're after. You'll find out once you try dragging the window with a mouse (it won't follow the mouse cursor, and only snap into place once the mouse button is released). I posted a link with the correct solution in a [comment](https://stackoverflow.com/questions/68273730/how-to-disable-focus-of-a-window-keep-it-always-on-top-by-using-python-win32-api#comment120666956_68273730) to your previous question. – IInspectable Jul 07 '21 at 09:33
  • here is the solution that worked for me: https://stackoverflow.com/questions/71458741/pyqt5-window-does-not-get-the-focus – Nabil Mustofa Dec 07 '22 at 18:15

1 Answers1

3

You need to get the HWND and then use SetWindowLong:

import win32gui
import win32con
from ctypes.wintypes import HWND
hw = HWND(int(self.winId()))
win32gui.SetWindowLong(hw, win32con.GWL_EXSTYLE, win32con.WS_EX_NOACTIVATE)
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • @NabilMustofa Do note that this will *replace* all extended styles on the window. If you want to *preserve* existing styles and just *add* the `WS_EX_NOACTIVATE` style, you need to call `GetWindowLong()` first, then `OR` the new style onto the result, and then pass the result to `SetWindowLong()`. – Remy Lebeau Jul 06 '21 at 23:02
  • @RemyLebeau I think you should point that out to the OP, I have only translated the command, nothing more :-) – eyllanesc Jul 06 '21 at 23:03
  • But this code is showing a type error! saying **TypeError: The object is not a PyHANDLE object.** (win32gui.SetWindowLong) – Nabil Mustofa Jul 07 '21 at 09:32
  • Can you show me how can I place it on my code? – Nabil Mustofa Jul 07 '21 at 09:53