0

Im creating an application with PyQt5. I wanted to create a widget that lives inside a frame and that the user can move and resize at will. Following this answer i came to the conclusion that i could use QDockWidgets to do this.

Thing is: i want my QDockWidget to only exist and be movable inside a frame of my mainwindow. It seems that setAllowedAreas() could do this restriction for me but it can only be used with QtDockWidgetAreas, and preexisting areas are just default areas of the main window.

So currently my code is like this:

#!/usr/local/bin/pydm

from PyQt5.QtWidgets import QDockWidget 

from pydm import Display

class Window(Display):     ##Main window class.
    def __init__(self, args, macros):
        super(Window, self).__init__(None, args, macros, 
            ui_filename="main.ui")

        self.pushButton.clicked.connect(self.createDock)

    def createDock(self):
        self.dock=QDockWidget()
        self.dock.raise_()
        self.dock.show()

(pydm is amodule that inherits all classes from PyQt and allows all default functionalities to work just fine.)

The main.ui file created with QtDesigner is just a widget window with a frame and a pushbutton. The generated window is in the image below:

enter image description here

So obviously my DockWidget can go outside the frame. I tried self.dock.setAllowedAreas(self.myFrame) but i got the expected error when clicking the button:

Traceback (most recent call last):
  File "./main.py", line 16, in createDock
    self.dock.setAllowedAreas(self.frame)
TypeError: setAllowedAreas(self, Union[Qt.DockWidgetAreas, Qt.DockWidgetArea]): argument 1 has unexpected type 'QFrame'

i also tried:

from PyQt5.QtCore import Qt

and in the createDock(self) function:

myArea = Qt.DockWidgetArea(self.frame)
self.dock.setAllowedAreas(myArea)

But i got:

Traceback (most recent call last):
  File "./main.py", line 17, in createDock

    myArea = Qt.DockWidgetArea(self.frame)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'QFrame'

Looking at the QDockWidgetArea it doesnt look that i can make a custom Area at all. At least not that i could find. Is there any way at all to achieve the functionality that i want?

  • 1
    As explained in the error, you must provide a valid area as argument, which is an `OR` combination of [`Qt.DockWidgetArea`](//doc.qt.io/qt-5/qt.html#DockWidgetArea-enum) enums. Besides, if you just want to prevent the floating feature, you don't need to set the allowed areas, but prevent the docking feature using [`setFeatures()`](//doc.qt.io/qt-5/qdockwidget.html#features-prop) with the appropriate flag combination. Note that you can do that directly from Designer, if the dockwidget was created there. I suggest to carefully read the *whole* QDockWidget documentation to understand how it works – musicamante Nov 16 '22 at 16:58
  • Thanks. I improved my code and move and resize the dockWIdgets inside main window only. But i still can only use addDockWidget within the main window by using self.parent().addDockWidget() (the parent() is because in pydm usually the Display object is child of mainWindow). The question "is there any way of creating a custom area? Or to restrict the movement of DockWidgets to only inside a frame?" remains. – Marco Montevechi Filho Nov 17 '22 at 02:18
  • I didn't know about PyDM until today, but its description is quite clear: "The goal is to provide a [...] system to make simple screens". What you're asking seems quite more than "simple screens". The QMainWindow interface only allows putting dock widgets around its borders (see the [documentation](//doc.qt.io/qt-5/qmainwindow.html#qt-main-window-framework). While it's *theoretically* possible to add a QMainWindow as a child of another window (and then add the docks to *that* window), this is not officially supported (which doesn't mean it's "impossible") and is probably not very reliable. – musicamante Nov 17 '22 at 02:42
  • 1
    Long story short, if you want advanced customization, PyDM is probably not what you're looking for, and you need to study more about the "real" Qt and get experienced with it, because it seems clear that what you need is out of the scope and purpose of PyDM. I sympathize with the need of a simple API, but the point is quite obvious: if you want something more advanced, that "simple API" is not sufficient anymore. – musicamante Nov 17 '22 at 02:47

0 Answers0