将 Qdockwidget 限制在一个象限而不是 Left/Right/Top/Bottom
Restrict a Qdockwidget to a quadrant rather than Left/Right/Top/Bottom
我有一个主 window 的三个主要部分,其中左侧(关键数据)应占据 window 的整个高度,而右侧的数据应分为顶部和底部。右下角的数据是相关的,但并不重要——这就是为什么我希望它是 un-dockable/closable.
Qt documentation 显示了一个用 C++ 编写的示例,但我不知道如何将其转换为 Python 代码,因为我没有 C++ 经验。
Qt Designer 应用程序将用户限制为 Left/Right/Top/Bottom,并且限制小部件的最大宽度不允许我占用未使用的 space(即不允许左侧的列表小部件占据主窗口的整个高度 window)
长话短说,要让 Qdockwidget 进入右下角,您必须在其上方放置另一个停靠小部件(它仍然限于 Right/Left/Top/Bottom DockWidgetArea)。看完下面 eyllanesc 的回答后,我将 post 两个解决方案。首先是他的代码的简化版本,然后是我最初 posted.
代码的修改版本
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 ##
我的回答是对这个例子的翻译:http://doc.qt.io/qt-5/qtwidgets-mainwindows-dockwidgets-example.html,所以未来的读者可以用它把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 ) which we \
will keep on account for you, or return at your request.""",
"""You made a small underpayment (less than ), 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 ). 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_())
完整的例子可以在下面link找到。 .qrc
文件已针对 Python 2 (dockwidgets_rc.py
) 编译,但对于 Python 3 您必须重新编译该文件。
我有一个主 window 的三个主要部分,其中左侧(关键数据)应占据 window 的整个高度,而右侧的数据应分为顶部和底部。右下角的数据是相关的,但并不重要——这就是为什么我希望它是 un-dockable/closable.
Qt documentation 显示了一个用 C++ 编写的示例,但我不知道如何将其转换为 Python 代码,因为我没有 C++ 经验。
Qt Designer 应用程序将用户限制为 Left/Right/Top/Bottom,并且限制小部件的最大宽度不允许我占用未使用的 space(即不允许左侧的列表小部件占据主窗口的整个高度 window)
长话短说,要让 Qdockwidget 进入右下角,您必须在其上方放置另一个停靠小部件(它仍然限于 Right/Left/Top/Bottom DockWidgetArea)。看完下面 eyllanesc 的回答后,我将 post 两个解决方案。首先是他的代码的简化版本,然后是我最初 posted.
代码的修改版本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 ##
我的回答是对这个例子的翻译:http://doc.qt.io/qt-5/qtwidgets-mainwindows-dockwidgets-example.html,所以未来的读者可以用它把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 ) which we \
will keep on account for you, or return at your request.""",
"""You made a small underpayment (less than ), 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 ). 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_())
完整的例子可以在下面link找到。 .qrc
文件已针对 Python 2 (dockwidgets_rc.py
) 编译,但对于 Python 3 您必须重新编译该文件。