在 PyQt 中关闭窗口后如何检索属性值?
Posted
技术标签:
【中文标题】在 PyQt 中关闭窗口后如何检索属性值?【英文标题】:How to retrieve an attribute value after closing a window in PyQt? 【发布时间】:2019-05-02 20:30:14 【问题描述】:我正在 PYQT5 的 MainWindow 中创建一个窗口。关闭新创建的窗口后,如何在主窗口中检索它的属性?我是 PYQT 的新手。如果我对在窗口内创建窗口的方法有误,请建议我
主窗口文件
class AssignmentSectionWindow (object):
courseID = ''
semester = ''
def __init__(self, courseID, semester):
self.courseID = courseID
self.semester = semester
def setupUi(self, assignmentSection):
assignmentSection.setObjectName("assignmentSection")
assignmentSection.resize(665, 506)
self.centralwidget = QtWidgets.QWidget(assignmentSection)
self.centralwidget.setObjectName("centralwidget")
self.assignmentLabel = QtWidgets.QLabel(self.centralwidget)
self.assignmentLabel.setGeometry(QtCore.QRect(30, 20, 231, 31))
self.assignmentLabel.setObjectName("assignmentLabel")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(20, 60, 591, 321))
self.widget.setObjectName("widget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.listWidget = QtWidgets.QListWidget(self.widget)
self.listWidget.setObjectName("listWidget")
self.horizontalLayout.addWidget(self.listWidget)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.verticalLayout.setContentsMargins(-1, 0, 0, 200)
self.verticalLayout.setObjectName("verticalLayout")
self.addAssignmentButton = QtWidgets.QPushButton(self.widget)
self.addAssignmentButton.setObjectName("addAssignmentButton")
self.verticalLayout.addWidget(self.addAssignmentButton)
self.editAssignmentButton = QtWidgets.QPushButton(self.widget)
self.editAssignmentButton.setObjectName("editAssignmentButton")
self.verticalLayout.addWidget(self.editAssignmentButton)
self.deleteAssignmentButton = QtWidgets.QPushButton(self.widget)
self.deleteAssignmentButton.setObjectName("deleteAssignmentButton")
self.verticalLayout.addWidget(self.deleteAssignmentButton)
self.horizontalLayout.addLayout(self.verticalLayout)
assignmentSection.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(assignmentSection)
self.menubar.setGeometry(QtCore.QRect(0, 0, 665, 22))
self.menubar.setObjectName("menubar")
assignmentSection.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(assignmentSection)
self.statusbar.setObjectName("statusbar")
assignmentSection.setStatusBar(self.statusbar)
self.retranslateUi(assignmentSection)
QtCore.QMetaObject.connectSlotsByName(assignmentSection)
self.addAssignmentButton.clicked.connect(lambda: (self.addAssignment()))
def addAssignment(self):
self.window = QtWidgets.QMainWindow()
self.ui = AddAssignmentWindow(self.courseID,self.semester)
self.ui.setupUi(self.window)
self.window
```
print(self.ui.fileName)
def editAssignment(self):
pass
def deleteAssignment(self):
pass
def retranslateUi(self, assignmentSection):
_translate = QtCore.QCoreApplication.translate
assignmentSection.setWindowTitle(_translate("assignmentSection", "Assignment Section"))
self.assignmentLabel.setText(_translate("assignmentSection", "Assignments of " + CommonUtils.getCourseNameFromCourseID(self.courseID)))
self.addAssignmentButton.setText(_translate("assignmentSection", "Add Assignment"))
self.editAssignmentButton.setText(_translate("assignmentSection", "Edit Assignment"))
self.deleteAssignmentButton.setText(_translate("assignmentSection", "Delete Assignment"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
assignmentSection = QtWidgets.QMainWindow()
ui = AssignmentSectionWindow("101","Fall2019")
ui.setupUi(assignmentSection)
assignmentSection.show()
sys.exit(app.exec_())
在主窗口中创建了这个窗口
class AddAssignmentWindow(object):
filePath = ''
fileName = ''
couresID = ''
semester = ''
def __init__(self, courseID, semester):
self.courseID = courseID
self.semester = semester
def setupUi(self, AddAssignment):
AddAssignment.setObjectName("AddAssignment")
AddAssignment.resize(644, 518)
self.centralwidget = QtWidgets.QWidget(AddAssignment)
self.centralwidget.setObjectName("centralwidget")
self.submitButton = QtWidgets.QPushButton(self.centralwidget)
self.submitButton.setGeometry(QtCore.QRect(280, 400, 113, 32))
self.submitButton.setObjectName("submitButton")
self.widget = QtWidgets.QWidget(self.centralwidget)
self.widget.setGeometry(QtCore.QRect(30, 40, 113, 191))
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.assignmentNameLabel = QtWidgets.QLabel(self.widget)
self.assignmentNameLabel.setObjectName("assignmentNameLabel")
self.verticalLayout.addWidget(self.assignmentNameLabel)
self.dueLabel = QtWidgets.QLabel(self.widget)
self.dueLabel.setObjectName("dueLabel")
self.verticalLayout.addWidget(self.dueLabel)
self.uploadFileLabel = QtWidgets.QLabel(self.widget)
self.uploadFileLabel.setObjectName("uploadFileLabel")
self.verticalLayout.addWidget(self.uploadFileLabel)
self.descriptionLabel = QtWidgets.QLabel(self.widget)
self.descriptionLabel.setObjectName("descriptionLabel")
self.verticalLayout.addWidget(self.descriptionLabel)
self.widget1 = QtWidgets.QWidget(self.centralwidget)
self.widget1.setGeometry(QtCore.QRect(160, 50, 231, 351))
self.widget1.setObjectName("widget1")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.widget1)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.assignmentNameLine = QtWidgets.QLineEdit(self.widget1)
self.assignmentNameLine.setObjectName("assignmentNameLine")
self.verticalLayout_2.addWidget(self.assignmentNameLine)
spacerItem = QtWidgets.QSpacerItem(20, 28, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem)
self.dueLine = QtWidgets.QDateTimeEdit(self.widget1)
self.dueLine.setCalendarPopup(True)
# TODO: self.dueLine.setDate(QtCore.QDateTime.currentDateTime())
self.dueLine.setObjectName("dueLine")
self.verticalLayout_2.addWidget(self.dueLine)
spacerItem1 = QtWidgets.QSpacerItem(20, 18, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem1)
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.uploadFileNameLine = QtWidgets.QLineEdit(self.widget1)
self.uploadFileNameLine.setObjectName("uploadFileNameLine")
self.horizontalLayout.addWidget(self.uploadFileNameLine)
self.browseButton = QtWidgets.QPushButton(self.widget1)
self.browseButton.setObjectName("browseButton")
self.horizontalLayout.addWidget(self.browseButton)
self.verticalLayout_2.addLayout(self.horizontalLayout)
self.desciptionText = QtWidgets.QTextEdit(self.widget1)
self.desciptionText.setObjectName("desciptionText")
self.verticalLayout_2.addWidget(self.desciptionText)
spacerItem2 = QtWidgets.QSpacerItem(20, 28, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem2)
AddAssignment.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(AddAssignment)
self.menubar.setGeometry(QtCore.QRect(0, 0, 644, 22))
self.menubar.setObjectName("menubar")
AddAssignment.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(AddAssignment)
self.statusbar.setObjectName("statusbar")
AddAssignment.setStatusBar(self.statusbar)
self.retranslateUi(AddAssignment)
QtCore.QMetaObject.connectSlotsByName(AddAssignment)
self.browseButton.clicked.connect(lambda: (self.browserFile()))
self.submitButton.clicked.connect(lambda: (self.submitButtonFunction()))
def browserFile(self):
options = QFileDialog.Options()
self.filePath, _ = QFileDialog.getOpenFileName(None, "Open file", "~/Desktop", '', '', options=options)
if (len(self.filePath) != 0):
print("File Path is", self.filePath)
self.fileName = QFileInfo(self.filePath).fileName()
self.uploadFileNameLine.setText(self.fileName)
def submitButtonFunction(self):
assignmentName =self.assignmentNameLine.text()
assignmentDue = self.dueLine.text()
description = self.desciptionText.toPlainText()
isSucess = AssignmentDB.postAssignmentToDB(self.courseID, assignmentName, self.filePath, self.fileName, assignmentDue, description, self.semester)
if (isSucess):
CommonUIUtils.showSuccessMessage("Successfully added Assignment")
def retranslateUi(self, AddAssignment):
_translate = QtCore.QCoreApplication.translate
AddAssignment.setWindowTitle(_translate("AddAssignment", "Add Assignment"))
self.submitButton.setText(_translate("AddAssignment", "Submit"))
self.assignmentNameLabel.setText(_translate("AddAssignment", "Assignment Name"))
self.dueLabel.setText(_translate("AddAssignment", "Assignment Due"))
self.uploadFileLabel.setText(_translate("AddAssignment", "Upload File"))
self.descriptionLabel.setText(_translate("AddAssignment", "Description"))
self.browseButton.setText(_translate("AddAssignment", "Browse"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
AddAssignment = QtWidgets.QMainWindow()
ui = AddAssignmentWindow()
ui.setupUi(AddAssignment)
AddAssignment.show()
sys.exit(app.exec_()))
我需要在 AssignmentSectionWindow 中访问 AddAssignmentWindow 的属性 FileName
【问题讨论】:
【参考方案1】:您必须考虑 Qt/PyQt 中的以下良好实践:
不要修改 Qt Designer 生成的代码,如消息所示:#WARNING!在此文件中所做的所有更改都将丢失! 当您使用 pyuic 生成 .py 时,因为如果您修改设计,所有编写的代码都将被删除。还有一个原因是 Qt Designer 生成的类不是小部件,而是用于填充小部件的接口类。更多信息here。
如果您想制作一个用于制作表单的小部件,请使用 QDialog,因为它允许知道应用程序何时关闭,以及通过方法 exec_() 选择用户。
使用布局设置元素。
如果没有必要,不要使用 lambda 方法。
在连接到信号的函数中使用装饰@QtCore.pyqtSlot(),因为它具有docs 中指出的几个优点。
考虑到上述情况,您的项目应具有以下结构:
.
├── AddAssignmentDialog.py
├── AssignmentSectionWindow.py
└── uis
├── AddAssignmentDialog.ui
└── AssignmentSectionWindow.ui
AddAssignmentDialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddAssignmentDialog</class>
<widget class="QDialog" name="AddAssignmentDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="assignmentNameLabel">
<property name="text">
<string>Assignment Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="assignmentNameLine"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="dueLabel">
<property name="text">
<string>Assignment Due</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="dueLine"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="uploadFileLabel">
<property name="text">
<string>Upload File</string>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="uploadFileNameLine"/>
</item>
<item>
<widget class="QPushButton" name="browseButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="descriptionLabel">
<property name="text">
<string>Description</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTextEdit" name="descriptionText"/>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="submitButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Submit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
AssignmentSectionWindow.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AssignmentSectionWindow</class>
<widget class="QMainWindow" name="AssignmentSectionWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>Assignment Section</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="assignmentLabel">
<property name="text">
<string>Assignments of %n </string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QListWidget" name="listWidget"/>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addAssignmentButton">
<property name="text">
<string>Add Assignment</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editAssignmentButton">
<property name="text">
<string>Edit Assignment</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteAssignmentButton">
<property name="text">
<string>Delete Assignment</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>23</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
然后将 .ui 转换为 .py:
pyuic5 uis/AddAssignmentDialog.ui -o AddAssignmentDialog_ui.py
pyuic5 uis/AssignmentSectionWindow.ui -o AssignmentSectionWindow_ui.py
得到如下结构:
.
├── AddAssignmentDialog.py
├── AddAssignmentDialog_ui.py
├── AssignmentSectionWindow.py
├── AssignmentSectionWindow_ui.py
└── uis
├── AddAssignmentDialog.ui
└── AssignmentSectionWindow.u
AddAssignmentDialog.py
from PyQt5 import QtCore, QtGui, QtWidgets
from AddAssignmentDialog_ui import Ui_AddAssignmentDialog
class AddAssignmentDialog(QtWidgets.QDialog, Ui_AddAssignmentDialog):
def __init__(self, parent=None):
super(AddAssignmentDialog, self).__init__(parent)
self.setupUi(self)
self.filename = ""
self.browseButton.clicked.connect(self.browserFile)
self.submitButton.clicked.connect(self.accept)
@QtCore.pyqtSlot()
def browserFile(self):
self.filename, _ = QtWidgets.QFileDialog.getOpenFileName(
None,
"Open file",
QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.DesktopLocation),
"",
"",
)
if self.filename:
finfo = QtCore.QFileInfo(self.filename)
self.uploadFileNameLine.setText(finfo.fileName())
def get_assignment(self):
assignmentName = self.assignmentNameLine.text()
assignmentDue = self.dueLine.text()
description = self.descriptionText.toPlainText()
return "name": assignmentName, "due": assignmentDue, "description": description
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = AddAssignmentDialog()
w.show()
sys.exit(app.exec_())
AssignmentSectionWindow.py
from PyQt5 import QtCore, QtGui, QtWidgets
from AssignmentSectionWindow_ui import Ui_AssignmentSectionWindow
from AddAssignmentDialog import AddAssignmentDialog
class AssignmentSectionWindow(QtWidgets.QMainWindow, Ui_AssignmentSectionWindow):
def __init__(self, parent=None):
super(AssignmentSectionWindow, self).__init__(parent)
self.setupUi(self)
self.addAssignmentButton.clicked.connect(self.addAssignment)
self.assignmentLabel.setText("Assignments of xxx")
@QtCore.pyqtSlot()
def addAssignment(self):
w = AddAssignmentDialog()
if w.exec_() == QtWidgets.QDialog.Accepted:
data = w.get_assignment()
print(data)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = AssignmentSectionWindow()
w.show()
sys.exit(app.exec_())
完整的例子可见here
【讨论】:
以上是关于在 PyQt 中关闭窗口后如何检索属性值?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Java 在 Selenium WebDriver 中关闭子浏览器窗口