QWidget关闭后如何打开QWidget?

时间:2019-06-21 09:30:11

标签: python python-3.x pyqt pyqt5

我有以下代码:

import os
from functools import partial
import numpy as np
from PyQt5 import QtCore, QtWidgets


class MainWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.resize(500, 500)
        self.setWindowFlags(
            self.windowFlags() | QtCore.Qt.MSWindowsFixedSizeDialogHint
        )
        self.setWindowTitle("nCode analysis set-up")

        self.wait_window = WaitWindow()

        thread = QtCore.QThread(self)
        thread.start()

        self.m_worker = Worker()
        self.m_worker.moveToThread(thread)
        self.m_worker.new_content_signal.connect(self.get_content)

        # Creating the top level grid layout
        mainGrid = QtWidgets.QGridLayout(self)

        self.analysis_type_label = QtWidgets.QLabel(self)
        self.analysis_type_label.setText("Type of analysis")
        mainGrid.addWidget(self.analysis_type_label, 0, 0)
        self.analysis_type_combo = QtWidgets.QComboBox(self)
        self.analysis_type_combo.addItems(["Fatigue", "Proof plus fatigue"])
        mainGrid.addWidget(self.analysis_type_combo, 0, 1, 1, 2)
        self.load_deck_type_label = QtWidgets.QLabel(self)
        self.load_deck_type_label.setText("Type of fatigue deck")
        mainGrid.addWidget(self.load_deck_type_label, 1, 0)
        self.load_deck_type_combo = QtWidgets.QComboBox(self)
        self.load_deck_type_combo.addItems(
            ["Regen braking", "No regen braking"]
        )
        mainGrid.addWidget(self.load_deck_type_combo, 1, 1, 1, 2)
        self.analysis_engine_type_label = QtWidgets.QLabel(self)
        self.analysis_engine_type_label.setText("Analysis Engine")
        mainGrid.addWidget(self.analysis_engine_type_label, 2, 0)
        self.analysis_engine_type_combo = QtWidgets.QComboBox(self)
        self.analysis_engine_type_combo.addItems(["EN analysis", "SN analysis"])
        mainGrid.addWidget(self.analysis_engine_type_combo, 2, 1, 1, 2)

        # Creating a scrolable area to accommodate for a large number of components with possible lenghty names
        self.scrollArea = QtWidgets.QScrollArea(self)
        # The line below is absolutely required to make the scrollable area work.
        self.scrollArea.setWidgetResizable(True)
        mainGrid.addWidget(self.scrollArea, 3, 0, 1, 3)
        self.secondaryWidget = QtWidgets.QWidget()
        self.scrollArea.setWidget(self.secondaryWidget)
        self.secondaryGrid = QtWidgets.QGridLayout(self.secondaryWidget)

        self.createDCL = QtWidgets.QPushButton(self)
        self.createDCL.setText("Create DCL")
        mainGrid.addWidget(self.createDCL, 4, 0, 1, 3)

    def start_task(self):
        if not os.path.exists("loading_database.db"):
            QtWidgets.QMessageBox.information(
                None,
                "Loading database missing",
                "Loading database has not been found. Creation of a new one will be attempted",
            )
            # self.loadingDatabaseCreator()
            QtWidgets.QMessageBox.information(
                None, "Successful", "Loading database succesfully created"
            )

        filePath, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "Select input model", "", "Input deck (*.inp)", "*.inp"
        )
        if filePath:
            self.wait_window.show()
            self.m_worker.finished.connect(self.wait_window.close)
            wrapper = partial(self.m_worker.read_file, filePath)
            # Launch the task in a reasonable time for the window to show
            QtCore.QTimer.singleShot(100, wrapper)
            w.show()
            self.wait_window.raise_()
            self.wait_window.activateWindow()

    @QtCore.pyqtSlot(int, str)
    def get_content(self, i, content):
        label = QtWidgets.QLabel("{} material".format(content))
        linedit = QtWidgets.QLineEdit(placeholderText="Drop material name here")
        linedit.setFixedWidth(150)
        button = QtWidgets.QPushButton("Pick material")

        self.secondaryGrid.addWidget(label, 2 + i, 0)
        self.secondaryGrid.addWidget(linedit, 2 + i, 1)
        self.secondaryGrid.addWidget(button, 2 + i, 2)


class WaitWindow(QtWidgets.QDialog):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Info")
        self.resize(600, 200)
        layout = QtWidgets.QVBoxLayout(self)
        self.message = QtWidgets.QLabel()
        self.message.setFixedWidth(550)
        self.message.setText("Please wait while input file is being read")
        layout.addWidget(self.message)


class Worker(QtCore.QObject):
    finished = QtCore.pyqtSignal()
    new_content_signal = QtCore.pyqtSignal(int, str)

    @QtCore.pyqtSlot(str)
    def read_file(self, fileName):
        i = 0
        collector_array = []
        with open(fileName, "r") as model_file_obj:
            for line in model_file_obj.readlines():
                if "*ELEMENT," in line and "DCOUP3D" not in line:
                    t = line.split("ELSET=")[1][:-1]
                    if t not in collector_array:
                        self.new_content_signal.emit(i, t)
                        QtCore.QThread.msleep(10)
                        collector_array.append(t)
                        i += 1
        self.finished.emit()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = MainWidget()
    w.start_task()
    sys.exit(app.exec_())

看起来很多代码,但是MainWidget首先被初始化。初始化之后,将调用MainWidget的{​​{1}}函数,该函数显示start_task QDialog,向用户询问开始解析的输入文件,然后显示WaitWindow QWidget窗口。虽然还算不错,但我希望用户在文件完成解析并且关闭MainWidget之前看不到MainWidget窗口。有什么想法吗?

1 个答案:

答案 0 :(得分:2)

我不明白您为什么使用w.show(),将其删除。

问题所在,如果要在执行任务后显示MainWidget,只需要将show方法连接到完成的信号上

# ...
self.m_worker.finished.connect(self.wait_window.close)
self.m_worker.finished.connect(self.show)
# ...