跨多个窗口访问项目和属性
Posted
技术标签:
【中文标题】跨多个窗口访问项目和属性【英文标题】:Access items and attributes across multiple windows 【发布时间】:2021-01-20 15:42:55 【问题描述】:我有一个主 GUI 窗口,我可以通过单击按钮打开一个新窗口(FCT 弹出窗口):
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.ui = Ui_MainWindow() # sets ui = to the main window from the ui-file
self.ui.setupUi(self)
[...]
def enter_fct_results(self):
self.FCTpopup = FCT_Window()
self.FCTpopup.show()
在窗口中,我有一个要填写的 QTable 和一个提交数据并关闭窗口的按钮:
class FCT_Window(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.ui = Ui_FCT_Window()
self.ui.setupUi(self)
[...]
self.ui.pushButton_submitFCT.clicked.connect(lambda: MainWindow.store_fct_data(MainWindow, self.on_submit()[0]))
def on_submit(self): # event when user clicks
fct_nparray = np.zeros((self.ui.tableFCTinputs.rowCount(), self.ui.tableFCTinputs.columnCount()))
for j in range(self.ui.tableFCTinputs.columnCount()):
for i in range(self.ui.tableFCTinputs.rowCount()):
fct_nparray[i, j] = float(self.ui.tableFCTinputs.item(i, j).text())
return fct_nparray, lambda: self.close()
self.ui.pushButton_submitFCT.clicked.connect(lambda: MainWindow.store_fct_data(MainWindow, self.on_submit()[0]))
主窗口中的接收函数如下所示:
def store_fct_data(self, data):
self.fct_data = data
现在我只想了解如何禁用主窗口或打开第二个窗口的按钮。在 enter_fct_results() 中禁用是可行的,但是如果我想使用 store_fct_data 或 on_submit 再次启用它,则会提供如下错误:
self.ui.pushButton_FCTresults.setEnabled(1)
self.ui.pushButton_submitFCT.clicked.connect(lambda: MainWindow.store_fct_data(MainWindow, self.on_submit()[0]))
AttributeError: type object 'MainWindow' has no attribute 'ui'
我不认为我在这里理解如何处理多个窗口和东西。例如,我将如何通过使用 window2 中的按钮来更改主窗口中按钮的颜色。我如何访问小部件?如果我在同一个窗口内,我很容易做到这一点
self.ui.pushbutton.setText("New Text")
我不知道如何跨 Windows 访问项目和属性:(你能帮帮我吗?
【问题讨论】:
请提供minimal reproducible example 【参考方案1】:访问另一个实例的属性
在enter_fct_results
中禁用第二个窗口的按钮与您在 lambda 中尝试的操作之间存在根本区别:在第一种情况下,您访问的是 instance 属性(例如, self.FCTpopup.ui.pushButton
),而在第二次你试图访问 class 属性。
self.ui
对象是在__init__
中创建的(当类实例创建时),所以instance 将有一个ui
属性,不是班级:
class Test:
def __init__(self):
self.value = True
test = Test()
print(test.value)
>>> True
print(Test.value)
>>> AttributeError: type object 'Test' has no attribute 'value'
提供一个参考
简单的解决方案是为第二个窗口为创建第一个窗口实例的引用:
def enter_fct_results(self):
self.FCTpopup = FCT_Window(self)
self.FCTpopup.show()
class FCT_Window(QMainWindow):
def __init__(self, mainWindow):
QMainWindow.__init__(self)
self.mainWindow = mainWindow
self.ui.pushButton_submitFCT.clicked.connect(self.doSomething)
def doSomething(self):
# ...
self.mainWindow.ui.pushButton.setEnabled(True)
使用模态窗口(又名对话框)
当某些临时交互(数据输入、文档预览等)需要窗口时,首选对话框:使用对话框的主要好处是它们对父级模态,防止在该父级上进行交互,直到对话框关闭;另一个好处是(至少在 Qt 上)它们在 exec()
函数中还有一个 blocking 事件循环,只有在对话框关闭后才会返回。这两个方面也使得不必要地禁用父窗口中的任何按钮。另一个重要的原因是 QMainWindow 不适合这种操作,也因为它具有通常不需要的功能(工具栏、状态栏、菜单等)。
def enter_fct_results(self):
self.FCTpopup = FCT_Window(self)
self.FCTpopup.exec_()
class FCT_Window(QDialog):
def __init__(self, parent):
QMainWindow.__init__(self, parent)
self.ui.pushButton_submitFCT.clicked.connect(self.doSomething)
def doSomething(self):
# ...
self.accept()
以上要求强制使用 QDialog(而不是 QMainWindow)在设计器中重新创建 ui。您可以创建一个新的并从原始的拖放小部件。
【讨论】:
【参考方案2】:我终于发现了我的错误:这是信号连接的地方。它必须在第二个窗口打开之前:
def enter_fct_results(self):
self.FCTpopup = Dialog(self.fct_data)
self.FCTpopup.submitted.connect(self.store_fct_data)
self.FCTpopup.exec_()
现在我可以将存储的数据从主窗口发送到打开的窗口,导入表格,编辑并在提交时将其发送回主窗口。
【讨论】:
以上是关于跨多个窗口访问项目和属性的主要内容,如果未能解决你的问题,请参考以下文章