Reputation: 349
I want to display a dialog with data if the evaluation of the data was successful.
In the Python 3 code below I created the function check_data()
to check the data. If the return value of this function is True
, the data_dialog
should be displayed.
It appears no error message when submitting the data entered in the textEdit
field, but there is no data_dialog
either.
What is wrong in the code?
main.py
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QListWidget
from PyQt5.uic import loadUi
from PyQt5.QtCore import pyqtSignal
class MainWindow(QMainWindow):
entered_text = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
loadUi("mainwindow.ui", self)
self.show()
def submit_text(self):
self.entered_text.emit(self.textEdit.toPlainText())
class DataDialog(QDialog):
def __init__(self, parent=None):
super().__init__()
self.list_widget = QListWidget(self)
self.list_widget.show()
def add_items(self, items):
self.list_widget.addItems(items)
def check_data(data_to_check=None):
print(data_to_check)
if data_to_check:
# TODO: Data evaluation code
# If data is as required, then
return True
def main():
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.pushButton_submit.clicked.connect(main_window.submit_text)
main_window.entered_text.connect(lambda data=main_window.entered_text: check_data(data))
if check_data():
data_dialog = DataDialog()
data_dialog.add_items(main_window.entered_text)
data_dialog.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
mainwindow.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>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="locale">
<locale language="English" country="UnitedKingdom"/>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTextEdit" name="textEdit"/>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton_submit">
<property name="locale">
<locale language="English" country="UnitedKingdom"/>
</property>
<property name="text">
<string>Submit</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>28</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Upvotes: 0
Views: 63
Reputation: 413
First thing, you need to move this block:
if check_data():
data_dialog = DataDialog()
...
data_dialog.show()
out of main()
since it's executed only once, on script call and is basically useless for your further work. Calling it in main_window.submit_text()
may be a better idea than trying to utilise a custom pyqtSignal
.
Second thing, there is no need for self.list_widget.show()
since list_widget
is a child of DataDialog
and is shown as soon as DataDialog
is active.
Third thing, DataDialog
needs to have a parent if you want to show it via show()
method; without parent, that will just silently fail. If you don't want that, you have to use exec_()
. I'd suggest using exec_()
anyway because it gives you return value from a QDialog
.
Fourth thing, you're passing a pyqtSignal
as a text, that will produce errors.
Fifth thing, you need to parse data from QTextEdit
since QListWidget.addItems()
accepts only itterables, not strings.
So, taken all of that into consideration, dirty fixup:
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QListWidget
from PyQt5.uic import loadUi
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
loadUi("mainwindow.ui", self)
self.show()
# Moved it here, it really felt out of place before main
# you can move it wherever you want, just remember to fix
# the method call
def check_data(self, data_to_check=None):
if data_to_check:
# TODO: Data evaluation code
# If data is as required, then
return True
def submit_text(self):
text = self.textEdit.toPlainText()
if self.check_data(text):
data_dialog = DataDialog(self)
# You need to parse text from textEdit to use it as
# QListWidget items! It's just a plain string!
data_dialog.add_items([text])
data_dialog.show()
class DataDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.list_widget = QListWidget(self)
def add_items(self, items):
self.list_widget.addItems(items)
def main():
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.pushButton_submit.clicked.connect(main_window.submit_text)
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Upvotes: 1
Reputation: 244311
In the main function the tasks are executed synchronously so at the beginning it will call check_data and since the data is empty this returns None which is equivalent to False so the dialog will not be shown, from which we deduce that you should not call to check_data in the main. Later when you connect the signal entered_text connects to check_data it will cause that when the signal is emitted it is invoked to check_data, but check_data only evaluates but it does not show any widget.
The idea is that the slot (function connected to the signal) does not return anything, but there the logic is executed, so I will create another function that makes the task of showing if it is necessary when entered_text indicates it.
#!/usr/bin/python3
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QListWidget, QVBoxLayout
from PyQt5.uic import loadUi
from PyQt5.QtCore import pyqtSignal
class MainWindow(QMainWindow):
entered_text = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
loadUi("mainwindow.ui", self)
self.pushButton_submit.clicked.connect(self.submit_text)
self.show()
def submit_text(self):
self.entered_text.emit(self.textEdit.toPlainText())
class DataDialog(QDialog):
def __init__(self, parent=None):
super().__init__()
lay = QVBoxLayout(self)
self.list_widget = QListWidget()
lay.addWidget(self.list_widget)
def add_items(self, item):
self.list_widget.addItem(item)
def check_data(data_to_check=None):
print(data_to_check)
if data_to_check:
# TODO: Data evaluation code
# If data is as required, then
return True
def main():
app = QApplication(sys.argv)
main_window = MainWindow()
def verify_data(text):
if check_data(text):
data_dialog = DataDialog()
data_dialog.add_items(text)
data_dialog.exec_()
main_window.entered_text.connect(verify_data)
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Upvotes: 1