QLabel未显示在QWidget窗口中

时间:2019-06-20 07:29:02

标签: python python-3.x pyqt pyqt5

我有下面这段代码,给出了下面的图片。

enter image description here

import os
import numpy as np
from PyQt5 import QtCore, QtWidgets
import sqlite3


class Ui_Form():

    def __init__(self):

        #Checking if the loading database is in place
        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')

        #Asking the user for the input file to be parsed and the number of componenets determined
        filePath, _ = QtWidgets.QFileDialog.getOpenFileName(None, "Select input model","","Input deck (*.inp)","*.inp")
        filePath = str(filePath)

        self.pleaseWait = waitWindow()
        self.pleaseWait.show()

        #If no file has been inputted the script will exit
        if not filePath:
            exit()
        else:
            #If a file has been inputted now it will be opened and a list containing all the lines will be created
            readInputFile(filePath)

           #Searching in the file for all the valid components. We disregards collectors containing RBE3 elements
           #as they don't require fatigue analysis
            self.pleaseWait.close()
            for line in model_file:
                if "*ELEMENT," in line and "DCOUP3D" not in line:
                    #If a valid collector is found it will be added to the array of type numpy.
                    try:
                        #Checks if the collector has already been recorded as different element types partaining of the same component
                        #will be specified in different collectors win the input deck
                        if not line.split("ELSET=")[1][:-1] in self.collector_array:
                            self.collector_array = np.concatenate((self.collector_array,np.array([line.split("ELSET=")[1][:-1]])),axis=0)
                    except:
                        self.collector_array = np.array([line.split("ELSET=")[1][:-1]])
            #model_file_obj.close

            #Testing to see if the array has been created indicating the presence of at least one entity
            #This will be useful if the user loads a load deck instead of a model as they have the same .inp extension
            try:
                self.collector_array
            except:
                QtWidgets.QMessageBox.information(None,'Error','File contains no element collectors')

            #Creating the initial Window
            self.mainWidget = QtWidgets.QWidget()
            self.mainWidget.resize(500, 500)
            self.mainWidget.setWindowFlags(self.mainWidget.windowFlags() | QtCore.Qt.MSWindowsFixedSizeDialogHint)
            self.mainWidget.setWindowTitle("nCode analysis set-up")

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

            #Creating the boxes which will describe the analysis to be written in the .dcl file
            self.analysis_type_label = QtWidgets.QLabel(self.mainWidget)
            self.analysis_type_label.setText("Type of analysis")
            self.mainGrid.addWidget(self.analysis_type_label,0,0)
            self.analysis_type_combo = QtWidgets.QComboBox(self.mainWidget)
            self.analysis_type_combo.addItems(["Fatigue","Proof plus fatigue"])
            self.mainGrid.addWidget(self.analysis_type_combo,0,1,1,2)
            self.load_deck_type_label = QtWidgets.QLabel(self.mainWidget)
            self.load_deck_type_label.setText("Type of fatigue deck")
            self.mainGrid.addWidget(self.load_deck_type_label,1,0)
            self.load_deck_type_combo = QtWidgets.QComboBox(self.mainWidget)
            self.load_deck_type_combo.addItems(["Regen braking","No regen braking"])
            self.mainGrid.addWidget(self.load_deck_type_combo,1,1,1,2)
            self.analysis_engine_type_label = QtWidgets.QLabel(self.mainWidget)
            self.analysis_engine_type_label.setText("Analysis Engine")
            self.mainGrid.addWidget(self.analysis_engine_type_label,2,0)
            self.analysis_engine_type_combo = QtWidgets.QComboBox(self.mainWidget)
            self.analysis_engine_type_combo.addItems(["EN analysis","SN analysis"])
            self.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.mainWidget)
            #The line below is absolutely required to make the scrollable area work.
            self.scrollArea.setWidgetResizable(True)
            self.mainGrid.addWidget(self.scrollArea,3,0,1,3)
            self.secondaryWidget = QtWidgets.QWidget()
            self.scrollArea.setWidget(self.secondaryWidget)
            self.secondaryGrid = QtWidgets.QGridLayout(self.secondaryWidget)

            #This bit creates the necessary object for every componenet that was found in the input deck.
            #The globals method is used to dynamically assign objects to variables for subsequent manipulation.
            for i in range(0, self.collector_array.shape[0]):
                globals()["self.materialLabel"+str(i)] = QtWidgets.QLabel(self.secondaryWidget)
                globals()["self.materialLabel"+str(i)].setText(self.collector_array[i]+" material")
                self.secondaryGrid.addWidget(globals()["self.materialLabel"+str(i)],2+i,0)
                globals()["self.materialName"+str(i)] = QtWidgets.QLineEdit(self.secondaryWidget)
                globals()["self.materialName"+str(i)].setPlaceholderText("Drop material name here")
                globals()["self.materialName"+str(i)].setFixedWidth(150)
                self.secondaryGrid.addWidget(globals()["self.materialName"+str(i)],2+i,1)
                globals()["self.materialPickingButton"+str(i)] = QtWidgets.QPushButton(self.secondaryWidget)
                globals()["self.materialPickingButton"+str(i)].setText("Pick material")
                globals()["self.materialPickingButton"+str(i)].clicked.connect(self.material_lookup)
                self.secondaryGrid.addWidget(globals()["self.materialPickingButton"+str(i)],2+i,2)

            #Creates the button that connects to the DLC_writer function
            self.createDCL = QtWidgets.QPushButton(self.mainWidget)
            self.createDCL.setText("Create DCL")
            self.mainGrid.addWidget(self.createDCL,4,0,1,3)
            self.createDCL.clicked.connect(self.DCL_guide)
            self.mainWidget.show()

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

class readInputFile():
    def __init__(self,filePath):
        model_file_obj = open(filePath, "r")
        globals()['model_file'] = model_file_obj.readlines()
        model_file_obj.close

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    ui = Ui_Form()
    sys.exit(app.exec_())

问题是此窗口中缺少我的文本标签。如果标签没有足够的空间来完全显示,我会做得很大,但在那种情况下,我认为它会显示它有足够的空间。希望有人知道为什么。

编辑:我已经包含了Ui_Form的整个 init 功能。我所有的问题都是由于其余的一切正常而引起的。

3 个答案:

答案 0 :(得分:2)

您正在查看的窗口不是请等待窗口,而是mainWidget窗口。

上面的解释假设:

  • 读取的文件很小,因此pleaseWait窗口将立即打开和关闭,这样,同步操作Qt将没有时间执行此操作,并且对于用户而言,该窗口将永远不会显示。对于这种情况,解决方案是给用户一个合理的时间来查看窗口。

  • 文件很大,读取将花费很长的时间来阻塞事件循环,这将导致诸如显示窗口之类的任务无法执行,以避免阻塞该任务必须在另一个线程中执行。 / p>

结合这两种解决方案,我们获得以下代码:

import os
from functools import partial
from PyQt5 import QtCore, QtWidgets


class Worker(QtCore.QObject):
    finished = QtCore.pyqtSignal()
    contentChanged = QtCore.pyqtSignal(list)

    @QtCore.pyqtSlot(str)
    def read_file(self, fileName):
        with open(fileName, "r") as model_file_obj:
            model_file = model_file_obj.readlines()
            print(model_file)
            self.contentChanged.emit(model_file)
        self.finished.emit()


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")
        mainGrid = QtWidgets.QGridLayout(self)

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

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

    def launch_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"
            )
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            None, "Select input model", "", "Input deck (*.inp)", "*.inp"
        )
        self.pleaseWait = WaitWindow()
        self.pleaseWait.show()
        self.m_worker.finished.connect(self.pleaseWait.close)
        wrapper = partial(self.m_worker.read_file, fileName)
        # Launch the task in a reasonable time for the window to show
        QtCore.QTimer.singleShot(100, wrapper)  #

    @QtCore.pyqtSlot(list)
    def get_content(self, lines):
        print(lines)


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)
        self.message.setFixedWidth(550)
        self.message.setText("Please wait while input file is being read")
        layout.addWidget(self.message)


if __name__ == "__main__":
    import sys

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

更新

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)

    @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.show()
    w.start_task()
    sys.exit(app.exec_())

答案 1 :(得分:1)

此代码最适合我:

import sys

from PyQt5 import QtWidgets
from PyQt5.Qt import QApplication


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

    def closeWindow(self):
        self.close()

app = QApplication(sys.argv)
w = waitWindow()
w.exec_()

enter image description here

答案 2 :(得分:0)

好吧,您拿走了代码,并剔除了所有不必要的内容,以分析实际问题,因为我已经包括了残破的版本,因此您可以查看将来有什么需要,看看有什么问题。

简而言之,问题在于您需要通过添加我要显示的标签来添加以下行作为waitWindow函数>> self.exec()的最后一行(请参见下面的代码)

现在说您确实还有另一个问题,那就是QDialog框将不允许程序在关闭之前继续运行(也就是它会停止进程流,直到您通过关闭窗口或使用其他方式释放程序为止) )。我的问题是,为什么不使用您的“主窗口”显示该消息,然后用其余数据重新填充。也很好奇为什么不使用QMainWindow?

import sys

from PyQt5.QtCore    import *
from PyQt5.QtGui     import *
from PyQt5.QtWidgets import *

class Ui_Form():
    def __init__(self):
        self.pleaseWait = waitWindow()
        self.pleaseWait.show() 

        self.pleaseWait.close()
        sys.exit()

class waitWindow(QDialog):
    def __init__(self):
        super(waitWindow, self).__init__()

        self.setWindowTitle("Info")
        self.resize(600,200)

        self.message = QLabel(self)
        self.message.setFixedWidth(550)
        self.message.setText("Please wait while input file is being read")

        self.VLayout = QVBoxLayout(self)
        self.VLayout.addWidget(self.message)

        self.setLayout(self.VLayout)
        self.exec_()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ui = Ui_Form()
    sys.exit(app.exec_())