gmarull / qtmodern

PyQt/PySide Widgets Modern User Interface
MIT License
745 stars 113 forks source link

Window resizing #1

Open mgrady3 opened 6 years ago

mgrady3 commented 6 years ago

Is it intended behavior for the frameless window to not be resizeable?

When I wrap my QMainWindow widget in a qtmodern.windows.ModernWindow it loses the ability to be resized by dragging the side or corner of the window.

My QMainWindow contains a number of dockable widgets. When these widgets are un-docked from the QMainWindow, they are resizeable via dragging however the ModernWindow is not.

gmarull commented 6 years ago

Hi,

This is actually a consequence of using a frameless window. Resizing, dragging, etc. needs to be implemented manually. Currently resizing is only possible if you place a Statusbar on the QMainWindow, as it includes a resizing point at the bottom right corner (see the example). I will investigate how to add full resizing capabilities.

-Gerard

mgrady3 commented 6 years ago

Thanks, I figured it was a result of using a frameless window style when I noticed the dockable widgets were able to be resized once undocked from the main widget. I'll poke around a bit in the qt docs and see if I can find anything useful for adding resize points manually.

gmarull commented 6 years ago

Hi,

An update on this issue. I have been doing some tests on macOS (following https://github.com/dfct/TrueFramelessWindow), and by tweaking some native window parameters I have been able to hide the window titlebar while keeping all functionality (buttons, resizing, snap, etc.). This is the portion of code that does the job (using PyObjC):

view = objc.objc_object(c_void_p=ctypes.c_void_p(int(self.winId())))
window = view._.window

window.setStyleMask_(
    window.styleMask() |
    Cocoa.NSFullSizeContentViewWindowMask)
window.setTitlebarAppearsTransparent_(True)
window.setTitleVisibility_(Cocoa.NSWindowTitleHidden)
osx

Doing the same on Windows is a bit trickier, I will spend some time on it. If everything works flawlessly on Python I will update the library, as using native methods does not require to re-implement all the window functionalities.

mgrady3 commented 6 years ago

As a quick workaround, I have gotten the resizing to work simply by manually adding a QSizeGrip to the widget being wrapped by qtmodern.windows.ModernWindow

An example is shown here: https://gist.github.com/mgrady3/c04890e44e6c89ed38246d77d0d6e2f7

bright2013 commented 5 years ago

I've received the suggestions for resizing the window. Hope this can be solved soon

Jerakin commented 5 years ago

@bright2013 This is far from none trivial. It would require manual look of mouse position comparing that to the edge of the window then changing MousePointer and so on. Quite a big change. For now you can add a statusBar with a QSizeGrip. (If use a QMainWindow you should get this automatically)

WBP20 commented 4 years ago

Hello, did you find any solution with mouse position ? or other except sizegrid?

maybe a clue below :

`
class App(QMainWindow):

def __init__(self):
    super().__init__()
    self.title = 'PyQt5 simple window - pythonspot.com'
    self.initUI()

def initUI(self):
    self.setWindowTitle(self.title)
    self.setWindowFlags(Qt.FramelessWindowHint)
    self.resize(640, 480)
    self.setWindowFlags(Qt.FramelessWindowHint)
    self.widget = QWidget()
    self.setCentralWidget(self.widget)
    self.show()
    self.setMouseTracking(True)
    self.widget.setMouseTracking(True)
    self.rightClick = False

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

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)

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

if name == 'main': app = QApplication(sys.argv) ex = App() sys.exit(app.exec_()) `

bactone commented 3 years ago

add a statusbar to widget is a simple way

bactone commented 3 years ago

image