Python Forum

Full Version: Drag and Move window from menubar
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello,

I got rid of Os windows frame because we cannot change colors. (I found clues on how to do it with C++ but can't find python's code).

Problem is we need to find a way to resize and move the windows, which could be easily found on the internet.

But I am stuck with the menubar, I can't move/resize anything from it. It seems like it is not considered as a part of the main windows. When the mouse is over it the mouse-event doesn't work.

Any idea how I could make it ? Or any link for homemade menubar-like ?

Here below is the code so far.

X=0
X2=8  
Y=0
Y2=30

class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'TEST'
        self.initUI()
        
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.resize(640, 480)
        self.widget = QWidget()
        self.setCentralWidget(self.widget)
        self.setMouseTracking(True)
        self.widget.setMouseTracking(True)
        self.rightClick = False
        self.leftClick = False
        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('Fichier')
        fileMenu2 = menubar.addMenu('Outils')
        fileMenu3 = menubar.addAction('Readme')
        
        self.menu2= QMenuBar(menubar)
        menubar.setCornerWidget(self.menu2, Qt.TopRightCorner)
        fileMenu4 = self.menu2.addAction(" -- ")
        fileMenu5 = self.menu2.addAction(" // ")
        Exit = self.menu2.addAction(" X ")
        Exit.triggered.connect(app.exit)

        self.show()
    
    def mousePressEvent(self, event):
        super(App, self).mousePressEvent(event)

        if event.button() == Qt.RightButton:
            self.rdragx = event.x()
            self.rdragy = event.y()        
            self.currentx = self.width()
            self.currenty = self.height()
            self.rightClick = True
        
        if event.button() == Qt.LeftButton:
            self.leftClick = True
            global X,Y
            X=event.pos().x()
            Y=event.pos().y()
    
    def mouseMoveEvent(self, event):
        super(App, self).mouseMoveEvent(event)
        
        width = self.frameGeometry().width()
        height = self.frameGeometry().height()
        width5 = width + 5
        widthm5 = width - 5
        height5 = height + 5
        heightm5 = height - 5

        posMouse = event.pos()
        posMouseX = event.x()
        posMouseY = event.y()
        
        if posMouseX >= widthm5 and posMouseX <= width5:
         QApplication.setOverrideCursor(Qt.SizeHorCursor)
        elif posMouseX >= -5 and posMouseX <= 5:
         QApplication.setOverrideCursor(Qt.SizeHorCursor)
        elif posMouseY >= heightm5 and posMouseY <= height5:
         QApplication.setOverrideCursor(Qt.SizeVerCursor)
        elif posMouseY >= -5 and posMouseY <= 5:
         QApplication.setOverrideCursor(Qt.SizeVerCursor)
        else:
         QApplication.restoreOverrideCursor()

        if self.rightClick == True:
           
            x = max(self.widget.minimumWidth(), 
                self.currentx + event.x() - self.rdragx)
            y = max(self.widget.minimumHeight(), 
                self.currenty + event.y() - self.rdragy)
            self.resize(x, y)
        
        if self.leftClick == True: 
            self.move(event.globalPos().x()-X-X2,event.globalPos().y()-Y-Y2)      

    def mouseReleaseEvent(self, event):
        super(App, self).mouseReleaseEvent(event)
        self.rightClick = False
        self.leftClick = False

    
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())
Thank you in advance,

WB
I modified your program to fill the main window with a big pushbutton
        self.setCentralWidget(QPushButton('Hello World', self))
        self.show()
Now there is no way to grab or move anything. There is nothing special about the menubar. The main window does not get mouse events if you click on a widget in the window. This makes sense because you are getting events for the window, and each widget has it's own window.

I think the way to do this (other than forget about the color of the frame and let the window manager handle this) is capture mouse events inside the menubar and use those to move the window (should only get mouse press events when not clicking on a menu or close button), and add resize widget "handles" to the side and bottom of the window.

Does the color bother you that much???? Can't you just change the background color?
Hello,

Thank you for your feedback. The problem is that the color of the app will be dark when color of the window manager bars colors are light, It looks like very strange.

Yes the point was to capture mouse events inside the menubar but as it is not really a widget and bound to QMainwindow I stuck finding a way to do it. I would appreaciate some help here.

Why is it so complicated to handle this when 90% of the app I use have their own top-level bars and not Windows managers frame ? Is it related to python /C++ only ?
Maybe eventFilter or event will work better. I wanted a QLineEdit where I could type a tab and not jump to the next window. Capturing keypress did not work because it was already too late, so I overrode event and looked for key events. Maybe looking at that level will work for you