pythonpython-3.xpyqtpyqt5

FramelessWindowHint & WindowStaysOnTopHint won't work


I want my PyQt5 program to be frameless and always be on top of the screen. When I use the WindowStayOnTopHint it works fine, but when I use it with the FramelessWindowHint it becomes frameless, but does not stay on top of the screen. After doing some research I found this, and it said to try to use setMask, but I could not get it to work.

Here is my code:

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QApplication, QLabel


class Invisible(QLabel):
 def __init__(self, **kwargs):
    super().__init__(**kwargs)
    self.__press_pos = None
    self.initUI()

 def initUI(self):
    self.setWindowFlags(Qt.WindowStaysOnTopHint)
    self.setMask() #This is where I use the setMask function, but it raises an error

    self.setAttribute(Qt.WA_TranslucentBackground)
    self.setText("Drag me...")
    self.setFont(QFont("Times", 50, QFont.Bold))
    self.adjustSize()  
    self.move(QApplication.instance().desktop().screen().rect().center()
              - self.rect().center())

 def mousePressEvent(self, event):
    if event.button() == Qt.LeftButton:
        self.__press_pos = event.pos()  

 def mouseReleaseEvent(self, event):
    if event.button() == Qt.LeftButton:
        self.__press_pos = None

 def mouseMoveEvent(self, event):
    if self.__press_pos:  
        self.move(self.pos() + (event.pos() - self.__press_pos))


 def main():
    app = QApplication(sys.argv)
    w = Invisible()
    w.show()
    return app.exec_()


if __name__ == '__main__':
   sys.exit(main())

This code gives me the error:

TypeError: arguments did not match any overloaded call:
  setMask(self, QBitmap): not enough arguments
  setMask(self, QRegion): not enough arguments

It is asking for more arguments, but when I give it more arguments it says that there are too many arguments. How do I fix this?


Solution

  • The problem in your case is that you must activate both properties with the operator |

    self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
    

    Complete code:

    import sys
    
    from PyQt5.QtCore import Qt, QPoint
    from PyQt5.QtGui import QFont
    from PyQt5.QtWidgets import QApplication, QLabel, QStyle
    
    
    class Invisible(QLabel):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.__press_pos = QPoint()
            self.initUI()
    
        def initUI(self):
            self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
            self.setAttribute(Qt.WA_TranslucentBackground)
            self.setText("Drag me...")
            self.setFont(QFont("Times", 50, QFont.Bold))
            self.adjustSize()
            self.setGeometry(
                QStyle.alignedRect(
                    Qt.LeftToRight,
                    Qt.AlignCenter,
                    self.size(),
                    QApplication.instance().desktop().availableGeometry()
                    )
                )
    
        def mousePressEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.__press_pos = event.pos()  
    
        def mouseReleaseEvent(self, event):
            if event.button() == Qt.LeftButton:
                self.__press_pos = QPoint()
    
        def mouseMoveEvent(self, event):
            if not self.__press_pos.isNull():  
                self.move(self.pos() + (event.pos() - self.__press_pos))
    
    def main():
        app = QApplication(sys.argv)
        w = Invisible()
        w.show()
        return app.exec_()
    
    
    if __name__ == '__main__':
       sys.exit(main())
    

    enter image description here

    setMask() serves to give a different border to the widget, for example for an example I got the following:

    enter image description here