Home > OS >  Repetitive PyQT references
Repetitive PyQT references

Time:10-21

I have a PyQT UI designed in QT Designer, with 40 figures (on different tabs), and a bunch of repetitive references to elements in the UI. For example, the following unique text fields, which are used to set the title of each figure.

    # Tab 1
    self.tab1_tl1.canvas.axes.set_title(self.tab1_tl1_title.text())
    self.tab1_tl2.canvas.axes.set_title(self.tab1_tl2_title.text())
    self.tab1_tl3.canvas.axes.set_title(self.tab1_tl3_title.text())
    self.tab1_tl4.canvas.axes.set_title(self.tab1_tl4_title.text())
    self.tab1_tl1.canvas.axes.set_ylabel(self.tab1_tl1_ylabel.text())
    self.tab1_tl2.canvas.axes.set_ylabel(self.tab1_tl2_ylabel.text())
    self.tab1_tl3.canvas.axes.set_ylabel(self.tab1_tl3_ylabel.text())
    self.tab1_tl4.canvas.axes.set_ylabel(self.tab1_tl4_ylabel.text())
    # Tab 2
    self.tab2_tl1.canvas.axes.set_title(self.tab2_tl1_title.text())
    self.tab2_tl2.canvas.axes.set_title(self.tab2_tl2_title.text())
    self.tab2_tl3.canvas.axes.set_title(self.tab2_tl3_title.text())
    self.tab2_tl4.canvas.axes.set_title(self.tab2_tl4_title.text())
    self.tab2_tl1.canvas.axes.set_ylabel(self.tab2_tl1_ylabel.text())
    self.tab2_tl2.canvas.axes.set_ylabel(self.tab2_tl2_ylabel.text())
    self.tab2_tl3.canvas.axes.set_ylabel(self.tab2_tl3_ylabel.text())
    self.tab2_tl4.canvas.axes.set_ylabel(self.tab2_tl4_ylabel.text())

As you can imagine, the code gets very wordy. Is there a more efficient way to loop through all these references and fields?

CodePudding user response:

As I said in the comments, you could use getattr, but without further context, this is the best I can suggest:

for i in range(1, 41):
    for j in range(1, 5):
        ax = getattr(self, f'tab{i}_tl{j}').canvas.axes
        title = getattr(self, f'tab{i}_tl{j}_title').text()
        ylabel = getattr(self, f'tab{i}_tl{j}_ylabel').text()
        ax.set_title(title)
        ax.set_ylabel(ylabel)

CodePudding user response:

You should put the corresponding tl, title and ylabel in a dictionary and arange them in a nested list instead of putting names as tab1_tl1

Create them like this:

tabs = [] 
for i in range(tabCount):
    tab = []
    tabs.append(tab)

    for j in range(tlCount):
        tab.append(dict(
          obj = create_tl(i,j)),
          title = create_title(i,j),
          ylabel = create_ylabel(i,j)  )
      

Now tabs[i][j] correspond to tabi_tlj and it is a dict containing the acutal tl object, the title and the ylabel. So you can update the properties like this:

for tab in tabs:        
    for tl in tab:
        tl['obj'].canvas.axes.set_title(tl['title'])
        tl['obj'].canvas.axes.set_ylabel(tl['ylabel'])

In general create numbered variables is not good. Lists are there for that. Also always gather related repeated objects in dicts or objects.

  • Related