0

All examples or documentation on PyQt5 QInputDialog I found, used simple classic lists limited to only one item per "row" (like in my code example ("Red","Blue" or "Green")).

I am searching for a good way to build a more detailed multidimensional list, like a table, where the user gets to see and select the whole row (with multiple values as one item) in the input dialog instead of a single value.

For example a nested list like that: [['Ryan', 24, 'm'], ['Lisa', 22, 'f'], ['Joe', 30, 'm']]

--> Imagine each one of the three lists in the list should be one row (entry) in the QInputDialog that can be selected. Like in a table with a checkbox for each row.

Is something like that possible? Anyone knows?

#The normal (limited) version with a simple list I am referring to looks like that:
def getChoice(self):
    itemlist = ("Red","Blue","Green")
    item, okPressed = QInputDialog.getItem(self, "Get item","Color:", itemlist, 0, False)
    if okPressed and item:
        print(item)
pppery
  • 3,731
  • 22
  • 33
  • 46
Kris
  • 27
  • 1
  • 6
  • I should add that a really _perfect_ solution would also allow to directly access all single parts of the selected row from the result, e.g. to further work with the information that the selected name was Joe (field 0) who is 30 years old (field 1). But if that is not possible a "combined display" version (in one string) also works good as the fallback... ;) – Kris Sep 18 '19 at 22:30
  • `name, years, gender = 'Ryan 24 m'.split()` – S. Nick Sep 18 '19 at 22:55
  • Yes, of course, but that's a hack with respect to "real" separate fields... ;) E.g. as soon as "Sara Jean" joins us, we have a problem... While we can technically solve that, introducing specific delimiter characters, it would not be a very elegant solution to make these visible to the users of the graphical dialog... But thanks anyway. – Kris Sep 20 '19 at 10:17
  • 1
    1. `_lst = [ x for x in 'Sara Jean 24 m'.split() ]` 2. `name, years, gender = [_lst if len(_lst)==3 else [_lst[0]+' '+_lst[1], _lst[-2], _lst[-1]]][0]` – S. Nick Sep 20 '19 at 11:25
  • Yes, I see your point and you're basically right, that every problem can be fixed (next problem can be fixed and next and so on), but that was not my point. I just wanted to show that the design of the approach itself is a bit hackish in comparison to real separated fields, like in a nested list. In this case at some point there is e.g. a string like "Theodor Karl Ludwig 101 m" and we have to implement the next fix for the last fix... The solution gets more and more complicated. – Kris Sep 20 '19 at 12:11
  • 1
    name, years, gender = [_lst if len(_lst)==3 else [' '.join(_lst[0:-2]), _lst[-2], _lst[-1]]][0] – S. Nick Sep 20 '19 at 12:24

1 Answers1

1

The join() method takes all items in an iterable and joins them into one string.

Syntax: string.join(iterable)

import sys
from PyQt5.QtCore import QTimer
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QLineEdit, QInputDialog, QLabel, QVBoxLayout


class PopupDialog(QtWidgets.QDialog):
    def __init__(self):
        super(PopupDialog, self).__init__()
        self.selected_item = None
        layout = QtWidgets.QFormLayout()
        self.setLayout(layout)
        self.setWindowTitle("New Popup")
        self.setMinimumWidth(400)

#        items = (['Ryan', 24, 'm'], ['Lisa', 22, 'f'], ['Joe', 30, 'm'])
        items = (['Ryan', '24', 'm'], ['Lisa', '22', 'f'], ['Joe', '30', 'm'])
        items = [ " ".join(item) for item in items ]                              # <<<-----<
        item, okPressed = QInputDialog.getItem(self, "Get item",
                          "Color:", items, 0, False)
        if okPressed and item:
            self.selected_item = item


class MainWindow(QtWidgets.QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setMinimumWidth(600)
        self.setWindowTitle("Main Window")
        self.le = QtWidgets.QLineEdit()
        button = QtWidgets.QPushButton("Select...")
        button.clicked.connect(self.get_input)
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.le)
        layout.addWidget(button)
        self.setLayout(layout)

    def get_input(self):
        popup = PopupDialog()
        print("got selection data: ", popup.selected_item)
        self.le.setText(popup.selected_item)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

enter image description here

S. Nick
  • 12,879
  • 8
  • 25
  • 33
  • That's a nice idea, thanks! Though not really keeping data in multiple fields, like in a table / nested list, it's an elegant trick to solve it using the normal string way. – Kris Sep 18 '19 at 22:12
  • Seems to be the answer for QInputDialog, though I would have hoped for real colums, but one can work with this. Probably for something like real tables (real lists of lists) other widgets / other approaches are needed... – Kris Sep 22 '19 at 22:34