设置QDialog框并保留对QDialog中元素的访问权限的最佳方法是什么?

时间:2017-12-11 13:41:56

标签: python python-3.x pyqt pyqt5 qdialog

我目前正在运行QDialog的这个实现,它可以满足我的需求,但似乎不是一种最佳实践方法,并且我似乎无法解决这些缺陷。我知道QDialog可以作为类或方法实现,但我需要能够访问QDialog的元素,如D1D2,我不知道怎么做除了我在下面列出的代码。与QLineEditQComboBox相关联的所有值都会立即应用,因此在关闭后不需要保留QDialog的副本。

  

Test.py

QComboBox
  

TestMainWindow.ui

QDialog
  

TestExampleDialog.ui

from PyQt5 import uic
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys

Ui_MainWindow = uic.loadUiType('TestMainWindow.ui')[0]
Ui_ExampleDialog = uic.loadUiType('TestExampleDialog.ui')[0]


class ExampleDialog(QDialog, Ui_ExampleDialog):

    def __init__(self, parent=None, flags=Qt.Dialog):
        QDialog.__init__(self, parent, flags)
        self.setupUi(self)


class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None, flags=Qt.Window):
        QMainWindow.__init__(self, parent, flags)
        self.setupUi(self)
        self.setWindowTitle('MCVE')

        # THIS DOES NOT SEEM APPROPRIATE, BUT I NEED TO ACCESS
        # ELEMENTS OF THE UI FILE OUTSIDE OF 'showExampleDialog'
        self.exampleDialog = ExampleDialog()

        self.itemInfoBtn.clicked.connect(self.showExampleDialog)
        self.setupItemInfo()

    def showExampleDialog(self):
        # ACCORDING TO PYCHARM 'self' IS 'QMainWindow',
        # DO I ASSUME THAT 'parent = QMainWindow'?
        self.exampleDialog.setWindowFlags(Qt.WindowCloseButtonHint)
        self.exampleDialog.closeButton.clicked.connect(self.exampleDialog.accept)
        self.exampleDialog.exec_()  # CREATES A TASKBAR ENTRY ... BUT WHY?

    def setupItemInfo(self):
        # THIS IS AN EXAMPLE OF HOW I'M CURRENTLY ACCESSING
        # ELEMENTS OF THE `showExampleDialog' DIALOG
        val = {'Entry #3', 'Entry #2', 'Entry #1'}
        self.exampleDialog.setWindowTitle('Example Dialog')
        self.exampleDialog.exampleCombo.insertItems(0, val)
        self.exampleDialog.exampleCombo.setCurrentIndex(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

我遇到的一个问题是<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>282</width> <height>173</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QPushButton" name="itemInfoBtn"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> <property name="text"> <string>ItemInfoBtn</string> </property> </widget> </item> </layout> </widget> </widget> <resources/> <connections/> </ui> <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="windowModality"> <enum>Qt::ApplicationModal</enum> </property> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>174</width> <height>98</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <property name="modal"> <bool>true</bool> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QLabel" name="Message"> <property name="text"> <string>I'm a Dialog ...</string> </property> <property name="alignment"> <set>Qt::AlignCenter</set> </property> </widget> </item> <item> <widget class="QComboBox" name="exampleCombo"/> </item> <item> <widget class="QPushButton" name="closeButton"> <property name="text"> <string>Close</string> </property> </widget> </item> </layout> </widget> <resources/> <connections/> </ui> 旁边创建了第二个任务栏条目。这对我来说没有意义。根据我的理解,QDialog可以是模态的,也可以是无模式的,我相信我当前的实现具有模态集。考虑到这一点,PyCharm说self是QMainWindow,所以我假设它继承了父进程,这应该阻止填充第二个任务栏条目。也许我错了。

我遇到的另一个问题是访问QMainWindow和变量的元素,当它作为一个类实现时,我不完全确定如何做到这一点,而我的研究还没有真正解释过的东西以一种易于理解的方式。

解决此问题的最佳方式是什么,以及如何阻止QDialog创建第二个任务栏条目?

1 个答案:

答案 0 :(得分:0)

这完全解决了这个问题。将自己分配到self.exampleDialog = ExampleDialog(self)并更新self.exampleDialog.setWindowFlags以包含self.exampleDialog.windowFlags()会消除第二个任务栏条目。

可以使用self.exampleDialog.<element>访问对话框的元素,例如self.exampleDialog.setWindowTitle('Example Dialog')

from PyQt5 import uic
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow
import sys

Ui_MainWindow = uic.loadUiType('TestMainWindow.ui')[0]
Ui_ExampleDialog = uic.loadUiType('TestExampleDialog.ui')[0]


class ExampleDialog(QDialog, Ui_ExampleDialog):
    def __init__(self, parent = None, flags = Qt.Dialog):
        QDialog.__init__(self, parent, flags)
        self.setupUi(self)


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent = None, flags = Qt.Window):
        QMainWindow.__init__(self, parent, flags)
        self.setupUi(self)
        self.setWindowTitle('MCVE')

        # Assign 'self' to 'ExampleDialog' so we can
        # access elements of the dialog.
        self.exampleDialog = ExampleDialog(self)

        self.itemInfoBtn.clicked.connect(self.showExampleDialog)
        self.setupItemInfo()

    def showExampleDialog(self):
        self.exampleDialog.setWindowFlags(self.exampleDialog.windowFlags() | Qt.WindowCloseButtonHint)
        self.exampleDialog.closeButton.clicked.connect(self.exampleDialog.accept)
        self.exampleDialog.exec_()  # CREATES A TASKBAR ENTRY ... BUT WHY?

    def setupItemInfo(self):
        val = {'Entry #3', 'Entry #2', 'Entry #1'}
        self.exampleDialog.setWindowTitle('Example Dialog')
        self.exampleDialog.exampleCombo.insertItems(0, val)
        self.exampleDialog.exampleCombo.setCurrentIndex(1)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())