Python 将Qdockwidget限制为象限,而不是左/右/上/下

Python 将Qdockwidget限制为象限,而不是左/右/上/下,python,pyqt4,qdockwidget,Python,Pyqt4,Qdockwidget,我有一个主窗口的三个主要部分,左侧(关键数据)应该占据整个窗口的高度,而右侧的数据应该在顶部和底部之间分割。右下角的数据是相关的,但不是关键的-这就是为什么我希望它是不可停靠/可关闭的 在C++中显示了一个例子,但是我不知道如何将它转换成Python代码,因为我没有C++经验。 Qt Designer应用程序将用户限制在左/右/上/下,并且限制小部件的最大宽度不允许我占用未使用的空间(即不允许左侧的列表小部件占据主窗口的整个高度) 长话短说,要将Qdockwidget放到右下角,您必须在其上方放

我有一个主窗口的三个主要部分,左侧(关键数据)应该占据整个窗口的高度,而右侧的数据应该在顶部和底部之间分割。右下角的数据是相关的,但不是关键的-这就是为什么我希望它是不可停靠/可关闭的

在C++中显示了一个例子,但是我不知道如何将它转换成Python代码,因为我没有C++经验。 Qt Designer应用程序将用户限制在左/右/上/下,并且限制小部件的最大宽度不允许我占用未使用的空间(即不允许左侧的列表小部件占据主窗口的整个高度)

长话短说,要将Qdockwidget放到右下角,您必须在其上方放置另一个dock widget(它仍然限于右/左/上/下DockWidgetArea)。在看了下面eyllanesc的答案后,我将发布两个解决方案。首先是他的代码的简化版本,然后是我最初发布的代码的修改版本

< Eyllanesc >从上面提到的C++例子中的翻译:

from PyQt4 import QtCore, QtGui

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.resize(600, 600)
        self.centralWidget = QtGui.QTextEdit()
        self.setCentralWidget(self.centralWidget)

        # Upper table widget
        dock = QtGui.QDockWidget("Upper", self.centralWidget)
        dock.setAllowedAreas(QtCore.Qt.RightDockWidgetArea)
        self.tableWidget = QtGui.QTableWidget(dock)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(6)
        self.tableWidget.setRowCount(7)
        for i in range(7):
            item = QtGui.QTableWidgetItem()
            self.tableWidget.setVerticalHeaderItem(i, item)
            self.tableWidget.verticalHeaderItem(i).setText("Item " + str(i + 1))
        for i in range(6):
            item = QtGui.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(i, item)
        dock.setWidget(self.tableWidget)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
        # Lower table widget
        dock = QtGui.QDockWidget("Lower", self.centralWidget)
        self.tableWidget_2 = QtGui.QTableWidget(dock)
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(6)
        self.tableWidget_2.setRowCount(7)
        for i in range(7):
            item = QtGui.QTableWidgetItem()
            self.tableWidget_2.setVerticalHeaderItem(i, item)
        for i in range(6):
            item = QtGui.QTableWidgetItem()
            self.tableWidget_2.setHorizontalHeaderItem(i, item)
        dock.setWidget(self.tableWidget_2);
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
        self.listWidget = QtGui.QListWidget(self.centralWidget)
        self.listWidget.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.listWidget.setObjectName("listWidget")
        for i in range(10):
            item = QtGui.QListWidgetItem()
            self.listWidget.addItem(item)
            item = self.listWidget.item(i)
            item.setText("Item " + str(i + 1))
        self.listWidget.setMinimumSize(QtCore.QSize(340, 600))
        self.setWindowTitle("Dock Widgets")

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
以及我最初使用的代码的修改版本:

from PyQt4 import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.listWidget = QtGui.QListWidget(self.centralwidget)
        self.listWidget.setObjectName("listWidget")
        self.gridLayout.addWidget(self.listWidget, 0, 0, 1, 1)
        self.listWidget.setLayoutDirection(QtCore.Qt.RightToLeft)
        for i in range(10):
            item = QtGui.QListWidgetItem()
            self.listWidget.addItem(item)
            item = self.listWidget.item(i)
            item.setText("Item " + str(i + 1))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.dockWidget = QtGui.QDockWidget(MainWindow)
        self.dockWidget.setFeatures(QtGui.QDockWidget.DockWidgetFloatable)
        self.dockWidget.setObjectName("dockWidget")
        self.dockWidgetContents = QtGui.QWidget()
        self.dockWidgetContents.setObjectName("dockWidgetContents")
        self.tableWidget = QtGui.QTableWidget(self.dockWidgetContents)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(6)
        self.tableWidget.setRowCount(7)
        for i in range(7):
            item = QtGui.QTableWidgetItem()
            self.tableWidget.setVerticalHeaderItem(i, item)
            self.tableWidget.verticalHeaderItem(i).setText("Item " + str(i + 1))
        for i in range(6):
            item = QtGui.QTableWidgetItem()
            self.tableWidget.setHorizontalHeaderItem(i, item)
        self.gridLayout_2 = QtGui.QGridLayout(self.dockWidgetContents)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.gridLayout_2.addWidget(self.tableWidget, 0, 0, 1, 1)
        self.dockWidget.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget)
        self.dockWidget_2 = QtGui.QDockWidget(MainWindow)
        self.dockWidget_2.setFeatures(QtGui.QDockWidget.DockWidgetClosable|QtGui.QDockWidget.DockWidgetFloatable)
        self.dockWidget_2.setObjectName("dockWidget_2")
        self.dockWidgetContents_2 = QtGui.QWidget()
        self.dockWidgetContents_2.setObjectName("dockWidgetContents_2")
        self.gridLayout_3 = QtGui.QGridLayout(self.dockWidgetContents_2)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.tableWidget_2 = QtGui.QTableWidget(self.dockWidgetContents)
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(6)
        self.tableWidget_2.setRowCount(7)
        for i in range(7):
            item = QtGui.QTableWidgetItem()
            self.tableWidget_2.setVerticalHeaderItem(i, item)
        for i in range(6):
            item = QtGui.QTableWidgetItem()
            self.tableWidget_2.setHorizontalHeaderItem(i, item)
        self.gridLayout_3.addWidget(self.tableWidget_2, 0, 0, 1, 1)
        self.dockWidget_2.setWidget(self.dockWidgetContents_2)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.dockWidget_2)
        MainWindow.setWindowTitle("MainWindow")
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())## Heading ##

我的答案是这个例子的翻译:所以将来读者可以用它来从C++代码到Python进行翻译。
from PyQt4 import QtCore, QtGui


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)

        self.textEdit = QtGui.QTextEdit()
        self.setCentralWidget(self.textEdit)

        self.createActions()
        self.createStatusBar()
        self.createDockWindows()

        self.setWindowTitle("Dock Widgets")

        self.newLetter()
        self.setUnifiedTitleAndToolBarOnMac(True)

    def newLetter(self):
        self.textEdit.clear()
        cursor = QtGui.QTextCursor(self.textEdit.textCursor())
        cursor.movePosition(QtGui.QTextCursor.Start)
        topFrame = cursor.currentFrame()
        topFrameFormat = topFrame.frameFormat()
        topFrameFormat.setPadding(16)
        topFrame.setFrameFormat(topFrameFormat)

        textFormat = QtGui.QTextCharFormat()
        boldFormat = QtGui.QTextCharFormat()
        boldFormat.setFontWeight(QtGui.QFont.Bold)
        italicFormat = QtGui.QTextCharFormat()
        italicFormat.setFontItalic(True)

        tableFormat = QtGui.QTextTableFormat()
        tableFormat.setBorder(1)
        tableFormat.setCellPadding(16)
        tableFormat.setAlignment(QtCore.Qt.AlignRight)
        cursor.insertTable(1, 1, tableFormat)
        cursor.insertText("The Firm", boldFormat)
        cursor.insertBlock()
        cursor.insertText("321 City Street", textFormat)
        cursor.insertBlock()
        cursor.insertText("Industry Park")
        cursor.insertBlock()
        cursor.insertText("Some Country")
        cursor.setPosition(topFrame.lastPosition())
        cursor.insertText(QtCore.QDate.currentDate().toString("d MMMM yyyy"), textFormat)
        cursor.insertBlock()
        cursor.insertBlock()
        cursor.insertText("Dear ", textFormat)
        cursor.insertText("NAME", italicFormat)
        cursor.insertText(",", textFormat)

        for i in range(3): 
            cursor.insertBlock()

        cursor.insertText("Yours sincerely,", textFormat)

        for i in range(3):  
            cursor.insertBlock()

        cursor.insertText("The Boss", textFormat)
        cursor.insertBlock()
        cursor.insertText("ADDRESS", italicFormat)

    def print_(self):
        document = self.textEdit.document()
        printer = QtGui.QPrinter()
        dlg = QtGui.QPrintDialog(printer, self)
        if dlg.exec() != QtGui.QDialog.Accepted: 
            return

        document.print_(printer)
        self.statusBar().showMessage("Ready", 2000)

    def save(self):
        fileName = QtGui.QFileDialog.getSaveFileName(self,
                        "Choose a file name", ".", "HTML document (*.html *.htm)")

        if not fileName:
            return

        file = QtCore.QFile(fileName)

        if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text):
            QtGui.QMessageBox.warning(self, "Dock Widgets",
                             "Cannot write file {}:\n{}."
                             .format(QtCore.QDir.toNativeSeparators(fileName), file.errorString()))
            return

        out = QTextStream(file)
        QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        out << textEdit.toHtml()
        QtGui.QApplication.restoreOverrideCursor()
        self.statusBar().showMessage("Saved '{}'".format(fileName), 2000)

    def undo(self):
        document = self.textEdit.document()
        document.undo()

    def insertCustomer(self, customer):
        if not customer:
            return
        customerList = customer.split(", ")
        document = self.textEdit.document()
        cursor = document.find("NAME")

        if not cursor.isNull():
            cursor.beginEditBlock()
            cursor.insertText(customerList[0])
            oldcursor = cursor
            cursor = document.find("ADDRESS")
            if not cursor.isNull():
                for c in customerList:
                    cursor.insertBlock()
                    cursor.insertText(c)

                cursor.endEditBlock()
            else:
                oldcursor.endEditBlock()

    def addParagraph(self, paragraph):
        if not paragraph:
            return
        document = self.textEdit.document()
        cursor = document.find("Yours sincerely,")

        if cursor.isNull():
            return

        cursor.beginEditBlock()
        cursor.movePosition(QtGui.QTextCursor.PreviousBlock, QtGui.QTextCursor.MoveAnchor, 2)
        cursor.insertBlock()
        cursor.insertText(paragraph)
        cursor.insertBlock()
        cursor.endEditBlock()

    def about(self):
        QtGui.QMessageBox.about(self, "About Dock Widgets",
               "The <b>Dock Widgets</b> example demonstrates how to "
               "use Qt's dock widgets. You can enter your own text, "
               "click a customer to add a customer name and "
               "address, and click standard paragraphs to add them.")

    def createActions(self):
        fileMenu = self.menuBar().addMenu("&File")
        fileToolBar = self.addToolBar("File")

        newIcon = QtGui.QIcon.fromTheme("document-new", QtGui.QIcon(":/images/new.png"))
        newLetterAct = QtGui.QAction(newIcon, "&New Letter", self)
        newLetterAct.setShortcuts(QtGui.QKeySequence.New)
        newLetterAct.setStatusTip("Create a new form letter")
        newLetterAct.triggered.connect(self.newLetter)
        fileMenu.addAction(newLetterAct)
        fileToolBar.addAction(newLetterAct)

        saveIcon = QtGui.QIcon.fromTheme("document-save", QtGui.QIcon(":/images/save.png"))
        saveAct = QtGui.QAction(saveIcon, "&Save...", self)
        saveAct.setShortcuts(QtGui.QKeySequence.Save)
        saveAct.setStatusTip("Save the current form letter")
        saveAct.triggered.connect(self.save)
        fileMenu.addAction(saveAct)
        fileToolBar.addAction(saveAct)

        printIcon = QtGui.QIcon.fromTheme("document-print", QtGui.QIcon(":/images/print.png"))
        printAct = QtGui.QAction(printIcon,"&Print...", self)
        printAct.setShortcuts(QtGui.QKeySequence.Print)
        printAct.setStatusTip("Print the current form letter")
        printAct.triggered.connect(self.print_)
        fileMenu.addAction(printAct)
        fileToolBar.addAction(printAct)

        fileMenu.addSeparator()

        quitAct = fileMenu.addAction("&Quit", self.close)
        quitAct.setShortcuts(QtGui.QKeySequence.Quit)
        quitAct.setStatusTip("Quit the application")

        editMenu = self.menuBar().addMenu("&Edit")
        editToolBar = self.addToolBar("Edit")
        undoIcon = QtGui.QIcon.fromTheme("edit-undo", QtGui.QIcon(":/images/undo.png"))
        undoAct = QtGui.QAction(undoIcon, "&Undo", self)
        undoAct.setShortcuts(QtGui.QKeySequence.Undo)
        undoAct.setStatusTip("Undo the last editing action")
        undoAct.triggered.connect(self.undo)
        editMenu.addAction(undoAct)
        editToolBar.addAction(undoAct)

        self.viewMenu = self.menuBar().addMenu("&View")

        self.menuBar().addSeparator()

        helpMenu = self.menuBar().addMenu("&Help")

        aboutAct = helpMenu.addAction("&About", self.about)
        aboutAct.setStatusTip("Show the application's About box")

        aboutQtAct = helpMenu.addAction("About &Qt", QtGui.qApp.aboutQt)
        aboutQtAct.setStatusTip("Show the Qt library's About box")

    def createStatusBar(self):
        self.statusBar().showMessage("Ready")

    def createDockWindows(self):
        dock = QtGui.QDockWidget("Customers", self)
        dock.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea)
        self.customerList = QtGui.QListWidget(dock)
        self.customerList.addItems([
            "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton",
            "Jane Doe, Memorabilia, 23 Watersedge, Beaton",
            "Tammy Shea, Tiblanka, 38 Sea Views, Carlton",
            "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal",
            "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston",
            "Sally Hobart, Tiroli Tea, 67 Long River, Fedula"])
        dock.setWidget(self.customerList)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
        self.viewMenu.addAction(dock.toggleViewAction())


        dock = QtGui.QDockWidget("Paragraphs", self)
        self.paragraphsList = QtGui.QListWidget(dock)
        self.paragraphsList.addItems([
            """Thank you for your payment which we have received today.""",
            """Your order has been dispatched and should be with you \
within 28 days.""",
            """We have dispatched those items that were in stock. The \
rest of your order will be dispatched once all the \
remaining items have arrived at our warehouse. No \
additional shipping charges will be made.""",
            """You made a small overpayment (less than $5) which we \
will keep on account for you, or return at your request.""",
            """You made a small underpayment (less than $1), but we have \
sent your order anyway. We'll add this underpayment to \
your next bill.""",
            """Unfortunately you did not send enough money. Please remit \
an additional $. Your order will be dispatched as soon as \
the complete amount has been received.""",
            """You made an overpayment (more than $5). Do you wish to \
buy more items, or should we return the excess to you?"""])

        dock.setWidget(self.paragraphsList);
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
        self.viewMenu.addAction(dock.toggleViewAction())

        self.customerList.currentTextChanged.connect(self.insertCustomer)
        self.paragraphsList.currentTextChanged.connect(self.addParagraph)

# import dockwidgets_rc

if __name__ == '__main__':
    import sys

    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())
从PyQt4导入QtCore,QtGui
类主窗口(QtGui.QMainWindow):
def uuu init uuu(self,parent=None):
QtGui.QMainWindow.\uuuuu init\uuuuu(self,parent)
self.textEdit=QtGui.QTextEdit()
self.setCentralWidget(self.textEdit)
self.createActions()
self.createStatusBar()
self.createDockWindows()
self.setWindowTitle(“停靠窗口小部件”)
self.newLetter()
self.setUnifiedTitle和ToolBaronMac(True)
def newLetter(自我):
self.textdedit.clear()
cursor=QtGui.QTextCursor(self.textEdit.textCursor())
cursor.movePosition(QtGui.QTextCursor.Start)
topFrame=cursor.currentFrame()
topFrameFormat=topFrame.frameFormat()
topFrameFormat.setPadding(16)
topFrame.setFrameFormat(topFrameFormat)
textFormat=QtGui.QTextCharFormat()
boldFormat=QtGui.QTextCharFormat()
boldFormat.setFontWeight(QtGui.QFont.Bold)
italicFormat=QtGui.QTextCharFormat()
italicFormat.setFontItalic(真)
tableFormat=QtGui.QTextTableFormat()
表格格式.订单(1)
tableFormat.setCellPadding(16)
tableFormat.setAlignment(QtCore.Qt.AlignRight)
cursor.insertTable(1,1,tableFormat)
cursor.insertText(“公司”,粗体格式)
cursor.insertBlock()
游标。插入文本(“321城市街”,文本格式)
cursor.insertBlock()
游标。插入文本(“工业园区”)
cursor.insertBlock()
cursor.insertText(“某个国家”)
cursor.setPosition(topFrame.lastPosition())
cursor.insertText(QtCore.QDate.currentDate().toString(“d MMMM yyyy”),textFormat)
cursor.insertBlock()
cursor.insertBlock()
cursor.insertText(“亲爱的”,textFormat)
游标。插入文本(“名称”,斜体格式)
cursor.insertText(“,”,textFormat)
对于范围(3)中的i:
cursor.insertBlock()
cursor.insertText(“您诚挚的,”,textFormat)
对于范围(3)中的i:
cursor.insertBlock()
cursor.insertText(“老板”,textFormat)
cursor.insertBlock()
游标。插入文本(“地址”,斜体格式)
def打印(自我):
document=self.textEdit.document()
printer=QtGui.QPrinter()
dlg=QtGui.QPrintDialog(打印机,自身)
如果dlg.exec()!=QtGui.QDialog.Accepted:
返回
文件打印(打印机)
self.statusBar().showMessage(“就绪”,2000年)
def保存(自我):
fileName=QtGui.QFileDialog.getSaveFileName(self,
“选择文件名”、“HTML文档(*.HTML*.htm)”)
如果不是文件名:
返回
file=QtCore.QFile(文件名)
如果不是file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text):
QtGui.QMessageBox.warning(self,“停靠小部件”,
“无法写入文件{}:\n{}。”
.format(QtCore.QDir.toNativeSeparators(文件名),file.errorString())
返回
out=QTextStream(文件)
QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)

我知道你没有QDockWidget@eyllanesc对-我不知道如何添加一个不会破坏我已有布局的。如果我使用BottomDockWidgetArea选项添加一个,那么在矩形模式中会有4个偏移部分,而不是在正方形模式中有3个偏移部分,并且dock不会在我试图获取它的位置。我想如果我没有用其他人必须删除的代码把它弄得乱七八糟的话,我会更容易得到帮助。我不太明白你到底想要什么,你把我和你的软件描述搞混了,你想移动什么部分,在什么空间,还有哪些部分没有?@eyllanesc我希望Qdockwidget占据主窗口右下角的空间(当前由“widget_3”占据,并填充有“tableWidget_2”)。取而代之的是一个Qdockwidget,它从左到右占据整个底部空间。这会阻止列表小部件从上到下正确地占据整个垂直空间(安装时会被dockwidget占用)。我认为这是不可能的,只有区域:上、下、左、右,没有交叉点。只有工会。