Создание динамических c текстовых полей с PyQt5 - PullRequest
0 голосов
/ 17 июня 2020

У меня есть следующий MU C, который производит следующие GUI (см. Рис. 1).

Fig 1

В зависимости от того, сколько изображений выбрано, текстовые поля появляются динамически . Имя изображения отображается в этих текстовых полях (см. Рис. 2).

Fig2

Теперь все в порядке, но я хочу расширить GUI, чтобы он извлекал важные параметры из imageename и печатает их рядом с TextBox, содержащим имя еще в двух TextBox (потому что есть два параметра (высота и ширина)). Я умею извлекать параметры, работает. Но я не знаю, как динамически добавить еще два TextBox по горизонтали. Затем я использую параметр для вычисления площади. Но я не могу изменить MU C так, чтобы он динамически добавлял желаемый TextBox (см. Рис. 3).

Fig3

Здесь вы можете увидеть MU C:

from PyQt5.QtGui import QFont, QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QApplication, QStyleFactory, QMainWindow, QWidget
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QLabel, QPushButton
from PyQt5.QtWidgets import QFileDialog, QLineEdit, QTextEdit
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QListView

from os import path as osPath

# Note this would most likely need a means to either re-size
# the window or better yet have a Scroll Area added to it
class OutWithLineEdits(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self)
        self.Parent = parent
        self.LneEdts = {}
        self.LneEdts[0] = QLineEdit()
        self.LE = {}
        self.LE[0] = QLineEdit()
        self.PrimrSet = False
        self.LstIndx = 0

        self.EditBox = QVBoxLayout()
        self.EditBox.addWidget(self.LneEdts[0])

        self.setLayout(self.EditBox)


    def SetImage(self, Text, Indx):
        print('Setting Image ', Indx, ')', Text)
        if Indx not in self.LneEdts.keys():
            self.LneEdts[Indx] = QLineEdit()
            self.LE[Indx] = QLineEdit()
            self.EditBox.addWidget(self.LneEdts[Indx])

        self.LneEdts[Indx].setText(Text)



# So here is how to make that (or any) GUI using straight Python-Qt
class LoadUI(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self)
        self.Parent = parent
        self.FileNameLst = []

        self.btnOpnImg = QPushButton('Open Image')
        self.btnOpnImg.clicked.connect(self.LoadImage)

        HBox1 = QHBoxLayout()
        HBox1.addWidget(self.btnOpnImg)
        HBox1.addStretch(1)

        Font = QFont()
        Font.setPointSize(16)
        Font.setBold(True)

        lblSelectd = QLabel('Your Selected Images:')
        lblSelectd.setFont(Font)

        HBox2 = QHBoxLayout()
        HBox2.addWidget(lblSelectd)
        HBox2.addStretch(1)

        # Comment-Out what you do not want to use and Uncomment-Out what you do
        # they have been made to be interchangable so you can see what each one
        # would look like

        # Now displaying the list of selected images could actually be done
        # several ways
        # 1) Your method of using QLineEdits
        self.OutPut = OutWithLineEdits(self)


        # 2) Using QLabels instead
        #self.OutPut = OutWithLabels(self)
        # 3) Using a QTextEdit instead
        #self.OutPut = OutWithTextEdit(self)
        # 4) Using a QListView instead
        #self.OutPut = OutWithListView(self)

        VBox = QVBoxLayout()
        VBox.addLayout(HBox1)
        VBox.addLayout(HBox2)
        VBox.addWidget(self.OutPut)
        VBox.addStretch(1)
        self.setLayout(VBox)

    # This is just a simple redirect or pass through method used for
    # ease of reading as well as implementation as modifying is very
    # easy later on
    @pyqtSlot()
    def LoadImage(self):
        FileData, NotUsed = QFileDialog.getOpenFileNames(self, 'Select Multi File', 'default', 'All Files (*)')

        if len(FileData) > 0:
            # Enumeration was unnecessary, especially since it was not used
            for FileItem in FileData:
                # Extract the File Name
                BaseName = osPath.basename(FileItem)
                self.FileNameLst.append(BaseName)

                if not self.OutPut.PrimrSet:
                    self.OutPut.PrimrSet = True
                    Indx = 0
                else:
                    self.OutPut.LstIndx += 1
                    Indx = self.OutPut.LstIndx

                self.OutPut.SetImage(BaseName, Indx)


# Keep your Main Window simple let it handle those things that are outside your
# actual Graphic User Interface such MenuToolBar, StatusBar, and Dockable Windows
# if you use any of these
class Fenster(QMainWindow):
    def __init__(self):
        # One should not use super( ) in Python as it introduces 4 known issues that
        # then must be handled properly. Further there were still actual bugs within
        # the usage of super( ) when used in Python as of early this year. So yes
        # while super( ) works fine within C++ it does not work as seamlessly within
        # Python due to the major  differences between these two languages. Next the
        # reason it was created was  to handle a rather rare issue and unless you are
        # doing some complicated inheritance you will most likely never run into this
        # extremely rare issue. However the 4 major issues that get included by using
        # super( ) are much more likely to occur than that rare issue its meant for to
        # solve. Of course using the basic explicit method, as follows, does not cause
        # these issues and is as just as simple as using `super( )` further you do not
        # actually gain anything useful by using `super( )` in Python that could not be
        # done in a much safer manner.
        QMainWindow.__init__(self)
        self.setWindowTitle('Image Selector')
        WinLeft = 550;
        WinTop = 150;
        WinWidth = 350;
        WinHigh = 300
        self.setGeometry(WinLeft, WinTop, WinWidth, WinHigh)

        # The Center Pane is your actual Main Graphic User Interface
        self.CenterPane = LoadUI(self)
        self.setCentralWidget(self.CenterPane)

        self.StatBar = self.statusBar()

    def DsplyStatMsg(self, MsgTxt):
        self.StatBar.showMessage(MsgTxt)


######MAIN####################
if __name__ == "__main__":
    # Unless you plan to do something with Command Line arguments no need
    # to include this and if you are you are better off using argparse
    # library as it handles Command Line arguments much more cleanly
    # app = QApplication(sys.argv)
    MainEventThred = QApplication([])

    MainApplication = Fenster()
    MainApplication.show()

    # This is the Qt4 method of doing this
    # sys.exit(app.exec_())
    # While this is the Qt5 method for doing this
    MainEventThred.exec() ```

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...