如果函数返回True

时间:2019-05-04 23:08:09

标签: python pyqt5

如果数据评估成功,我想显示一个包含数据的对话框。

在下面的Python 3代码中,我创建了函数check_data()来检查数据。如果此函数的返回值为True,则应显示data_dialog

提交在textEdit字段中输入的数据时,没有出现错误消息,但也没有data_dialog

代码有什么问题?

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>

2 个答案:

答案 0 :(得分:1)

在主函数中,任务是同步执行的,因此在开始时它将调用check_data,并且由于数据为空,因此返回None,它等效于False,因此将不会显示该对话框,由此我们推断出您不应调用main中的check_data。稍后,当您连接信号enter_text连接到check_data时,它将导致在发出信号时将其调用到check_data,但是check_data仅评估但不显示任何小部件。

这个想法是插槽(连接到信号的函数)不返回任何东西,但是执行了逻辑,因此我将创建另一个函数,该函数负责在enter_text指示它时显示是否有必要。 / p>

#!/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()

答案 1 :(得分:1)

首先,您需要移动此块:

if check_data():
    data_dialog = DataDialog()
    ...
    data_dialog.show()
main()中的

,因为它仅在脚本调用时执行一次,并且对于您的进一步工作基本上没有用。与尝试利用自定义main_window.submit_text()相比,在pyqtSignal中调用它可能是一个更好的主意。

第二件事,由于self.list_widget.show()list_widget的子代,并且DataDialog处于活动状态时会立即显示,因此不需要DataDialog

第三,如果要通过DataDialog方法显示show(),则需要有一个父项;没有父母,只会默默地失败。如果您不想这样做,则必须使用exec_()。我还是建议您使用exec_(),因为它会给您QDialog的返回值。

第四件事,您正在传递pyqtSignal作为文本,这会产生错误。

第五件事,您需要解析QTextEdit中的数据,因为QListWidget.addItems()仅接受可写内容,而不接受字符串。

因此,考虑到所有这些,肮脏的修正:

#!/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()