I'm currently running this implementation of QDialog, which works for what I need, but doesn't seem like a best practice approach, and there are flaws that I can't seem to work around. I know QDialog can be implemented as a Class or Method, but I need to be able to access elements of QDialog like QLineEdit
and QComboBox
, and I'm not sure how to do this other than the code I have listed below. All of the values associated with the QComboBox
in the QDialog
are applied immediately, so there is no need to keep a copy of the QDialog around after it has been closed.
Test.py
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_())
TestMainWindow.ui
<?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>
TestExampleDialog.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>
One of the issues I have is that QDialog
creates a second taskbar entry beside the QMainWindow
one. This does not make sense to me. From my understanding, QDialog
can be either modal or modeless, and I believe my current implementation has the modal set. With that in mind, PyCharm says self is QMainWindow so I assume that it is inheriting the parent which should prevent a second Taskbar entry from populating. Perhaps I'm wrong about that.
The other issue I have is accessing elements of the QDialog
and variables when it has been implemented as a class, I'm not entire sure how to do that, and my research has not really explained things in a easy to understand way.
What would be the best way to approach this, and how can I prevent the QDialog
from creating a second taskbar entry?
This fixes the issue completely. Assigning self to self.exampleDialog = ExampleDialog(self)
and updating self.exampleDialog.setWindowFlags
to include self.exampleDialog.windowFlags()
eliminates the second taskbar entry.
Elements of the dialog can be accessed using self.exampleDialog.<element>
for example 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_())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.