質問

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()
役に立ちましたか?

解決

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.

他のヒント

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") 
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top