I which to bring back to initial state an Undocked or floated QDockWidget
with a QPushButton.
from PyQt5 import QtCore, QtGui, QtWidgets
class Mainwindow(object):
def setupUi(self, window):
window.setObjectName("window")
window.resize(309, 148)
self.centralwidget = QtWidgets.QWidget(window)
self.centralwidget.setObjectName("centralwidget")
self.Undock_btn = QtWidgets.QPushButton(self.centralwidget)
self.Undock_btn.setGeometry(QtCore.QRect(4, 4, 100, 22))
self.Undock_btn.setStyleSheet("background: rgba(255, 217, 90, 255)\n")
self.Undock_btn.setObjectName("Undock_btn")
self.ReDock_btn = QtWidgets.QPushButton(self.centralwidget)
self.ReDock_btn.setGeometry(QtCore.QRect(110, 4, 96, 22))
self.ReDock_btn.setStyleSheet("background:rgba(9, 17, 188, 109);")
self.ReDock_btn.setObjectName("ReDock_btn")
self.dockw = QtWidgets.QDockWidget(self.centralwidget)
self.dockw.setTitleBarWidget(None)
self.dockw.setGeometry(QtCore.QRect(4, 34, 200, 110))
self.dockw.setStyleSheet("background:rgba( 0,188, 0, 29);\n")
self.dockw.setObjectName("dockw")
self.dockWidgetContents = QtWidgets.QWidget()
self.dockWidgetContents.setObjectName("dockWidgetContents")
self.dockw.setWidget(self.dockWidgetContents)
window.setCentralWidget(self.centralwidget)
self.retranslateUi(window)
QtCore.QMetaObject.connectSlotsByName(window)
#-----------------------------------------------------------------
self.Undock_btn.setCheckable(True)
self.connexions()
def connexions(self):
self.Undock_btn.clicked.connect(self.Method_Float_it)
self.ReDock_btn.clicked.connect(self.Method_BringBack)
def Method_Float_it(self):
print("Method_Float_it")
self.dockw.setFloating(True)
if self.dockw.isFloating():
print("is Floating now...")
return True
def Method_BringBack(self):
self.dockw.setFloating(False)
self.dockw.RestoreState(True)
def retranslateUi(self, window):
_translate = QtCore.QCoreApplication.translate
window.setWindowTitle(_translate("window", "GUI"))
self.Undock_btn.setText(_translate("window", "UnDock Button"))
self.ReDock_btn.setText(_translate("window", "Bring back button"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QMainWindow()
ui = Mainwindow()
ui.setupUi(window)
window.show()
sys.exit(app.exec_())
image of when it's floated after pressed QPushButton
The Problem is : after I undocked the QDockWidget with first button, the second button fails to bring it back to normal (initial state)
The "main" issue is that you're not correctly adding the dock widget to the window, as the right way to do it is using the addDockWidget()
method of QMainWindow.
What you actually did was to create the dock widget as a child of the central widget, and that's not a valid approach.
Your first function "works" just because when setFloating(True)
is called, QDockWidget changes its window flags and ensures that it becomes a top level window.
The restore function doesn't work because the dock widget has never been correctly added to the main window, so it has no reference to know where it should "dock back".
The solution, theoretically , would be to add this line after the dock widget is created:
window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.dockw)
But, it would be only a partial solution, as your code has two other major problems.
There are two other (relatively) minor issues:
RestoreState
is, but it certainly is not a member of QDockWidget, nor of Qt with the uppercase R, as the only restoreState()
functions in Qt (for QMainWindow, QSplitter, etc) require a QByteArray, not a bool; I fixed your code, it is working now as expected. All variables functions and methods should be either some_function_name
or someFunctionName
, the former is called C style and the latter Java style. Further, your class has to inherit from QMainWindow
, and a QLayout
has to be added to every QWidget
. Then, the subwidgets are added to the QLayout
with QLayout.addWidget
. Following the code, where i added some comments for explanation.
#!/usr/bin/python3
#-*-coding: utf-8-*-
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Mainwindow(QtWidgets.QMainWindow):
def setupUI(self):
self.setObjectName("window")
self.resize(309, 148)
self.centralWid = QtWidgets.QWidget(self) # not naming it centralWidget, because that would override the centralWidget() function of QMainWindow
self.centralWid.setObjectName("centralwidget")
self.centralLay = QtWidgets.QHBoxLayout(self.centralWid) # create a layout
self.centralWid.setLayout(self.centralLay) # and set it on the central widget
self.setCentralWidget(self.centralWid) # set centralWidget as the centralWidget of the window
self.undockButton = QtWidgets.QPushButton(self.centralWid)
self.undockButton.setStyleSheet("background: rgba(255, 217, 90, 255);")
self.undockButton.setObjectName("undockbutton")
self.centralLay.addWidget(self.undockButton)
self.redockButton = QtWidgets.QPushButton(self.centralWid)
self.redockButton.setStyleSheet("background: rgba(9, 17, 188, 109);")
self.redockButton.setObjectName("redockButton")
self.centralLay.addWidget(self.redockButton)
self.dock = QtWidgets.QDockWidget("Dock title", self.centralWid)
self.dock.setTitleBarWidget(None)
self.dock.setStyleSheet("background: rgba( 0,188, 0, 29);")
self.dock.setObjectName("dock")
self.dockContents = QtWidgets.QWidget()
self.dockContents.setObjectName("dockcontents")
self.dock.setWidget(self.dockContents)
self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dock)
self.translateUI()
QtCore.QMetaObject.connectSlotsByName(self)
self.connectSlots()
def connectSlots(self):
self.undockButton.clicked.connect(self.undock)
self.redockButton.clicked.connect(self.redock)
def undock(self):
self.dock.setFloating(True)
def redock(self):
if self.dock.isFloating():
self.dock.setFloating(False)
def translateUI(self):
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("window", "Window"))
self.undockButton.setText(_translate("window", "Undock"))
self.redockButton.setText(_translate("window", "Redock"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = Mainwindow()
mainWin.setupUI()
mainWin.show()
sys.exit(app.exec_())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.