Question

I am working on a GUI with pyqt and pyqtgraph. In my application, I have 10 tabbed imageview, I was wondering how I could convert the following which takes too many lines with a more elegant pythonic way to address these objects. So instead of something like this:

img1 = pg.ImageView() 
img2 = pg.ImageView() 
img3 = pg.ImageView()
img4 = pg.ImageView()
img5 = pg.ImageView()
img6 = pg.ImageView()
img7 = pg.ImageView()
img8 = pg.ImageView()
img9 = pg.ImageView()
img10 = pg.ImageView()


tab_widget = QtGui.QTabWidget() 
tab1 = QtGui.QWidget() 
tab2 = QtGui.QWidget() 
tab3 = QtGui.QWidget() 
tab4 = QtGui.QWidget() 
tab5 = QtGui.QWidget() 
tab6 = QtGui.QWidget() 
tab7 = QtGui.QWidget() 
tab8 = QtGui.QWidget() 
tab9 = QtGui.QWidget() 
tab10 = QtGui.QWidget() 

p1_vertical = QtGui.QVBoxLayout(tab1) 
p2_vertical = QtGui.QVBoxLayout(tab2) 
p3_vertical = QtGui.QVBoxLayout(tab3) 
p4_vertical = QtGui.QVBoxLayout(tab4) 
p5_vertical = QtGui.QVBoxLayout(tab5) 
p6_vertical = QtGui.QVBoxLayout(tab6) 
p7_vertical = QtGui.QVBoxLayout(tab7) 
p8_vertical = QtGui.QVBoxLayout(tab8) 
p9_vertical = QtGui.QVBoxLayout(tab9) 
p10_vertical = QtGui.QVBoxLayout(tab10) 

tab_widget.addTab(tab1, "Grid 1") 
tab_widget.addTab(tab2, "Grid 2")
tab_widget.addTab(tab3, "Grid 3") 
tab_widget.addTab(tab4, "Grid 4") 
tab_widget.addTab(tab5, "Grid 5") 
tab_widget.addTab(tab6, "Grid 6") 
tab_widget.addTab(tab7, "Grid 7") 
tab_widget.addTab(tab8, "Grid 8") 
tab_widget.addTab(tab9, "Grid 9") 
tab_widget.addTab(tab10, "Grid 10")  

button1 = QtGui.QPushButton("button1") 
p1_vertical.addWidget(img1)
p2_vertical.addWidget(img2) 
p3_vertical.addWidget(img3) 
p4_vertical.addWidget(img4) 
p5_vertical.addWidget(img5) 
p6_vertical.addWidget(img6) 
p7_vertical.addWidget(img7) 
p8_vertical.addWidget(img8) 
p9_vertical.addWidget(img9)  
p10_vertical.addWidget(img10) 

Perhaps something like this:

d = {} 
for i in range(1,10):
    d["img{0}".format(i)]= pg.ImageView()
Était-ce utile?

La solution

Create a custom widget class that does all the setup in its __init__:

class ImageViewTab(QtGui.QWidget):
    def __init__(self, parent=None)
        super(ImageViewTab, self).__init__(parent)
        layout = QtGui.QVBoxLayout(self)
        self.imageview = pg.ImageView(self)
        layout.addWidget(self.imageview)

then add instances of your widget to the tab-widget in a loop:

    tab_widget = QtGui.QTabWidget()
    for index in range(1, 11):
        widget = ImageViewTab(tab_widget)
        tab_widget.addTab(widget, 'Grid %s' % index)

After all the setup is done, you can use the QTabWidget.widget method access the widgets by index:

    widget = tab_widget.widget(4)
    widget.imageview.setImage(img)

The main benefit of this approach is that it is very flexible. You can add specialized methods to your custom class, create and emit custom signals, add slots, etc.

Autres conseils

imgs = [pg.ImageView() for _ in range(10)]

tab_widget = QtGui.QTabWidget()

tabs = [QtGui.QWidget() for _ in range(10)]

p_verticals = [QtGui.QVBoxLayout(tab) for tab in tabs]

for n, tab in enumerate(tabs):
    tab_widget.addTab(tab, "Grid {0}".format(n+1))

button1 = QtGui.QPushButton("button1")

for p, img in zip(p_verticals, imgs):
    p.addWidget(img)

I don't see why you would want to use a dictionary, lists are fine.

You can create all your variables in lists:

    imgs = [pg.ImageView() for _ in range(10)]
    tab_widget = QtGui.QTabWidget() 
    tabs = [QtGui.QWidget() for _ in range(10)]
    p_verticals = [QtGui.QVBoxLayout(tabs[i]) for i in range(10)]
    for i in range(10):
        tab_widget.addTab(tab[i], "Grid %d" % i+1) 
        p_verticals[i].addWidget(imgs[i])
    button1 = QtGui.QPushButton("button1") 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top