Sadie LaBounty
Sadie LaBounty

Reputation: 379

PyQt - Create Menus With For Loops:

I have a CSV file of analytics data in the form

Continent:     CT:  Country:    Count:
North America  GT   Guatemala   1
...            ...  ...         ...

that I want to use to make a 'Country' menu within my PyQT GUI which will look like this:

Menu made manually

As you can see, I want to first create a continent menu (Popular Countries can be ignored) and then add countries to each continent as they appear in the data. So far, I have this code, which does nothing but load a blank GUI:

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
    MainWindow.setObjectName(_fromUtf8("Country-Wise Analytics"))
    MainWindow.resize(900, 700)

    self.menubar = QtGui.QMenuBar(MainWindow)
    self.menubar.setGeometry(QtCore.QRect(0, 0, 867, 22))
    self.menubar.setObjectName(_fromUtf8("menubar"))
    self.menuCountry = QtGui.QMenu(self.menubar)
    self.menuCountry.setObjectName(_fromUtf8("menuCountry"))
    self.menuPlatform = QtGui.QMenu(self.menubar)
    self.menuPlatform.setObjectName(_fromUtf8("menuPlatform"))
    MainWindow.setMenuBar(self.menubar)
    self.statusbar = QtGui.QStatusBar(MainWindow)
    self.statusbar.setObjectName(_fromUtf8("statusbar"))
    MainWindow.setStatusBar(self.statusbar)

    cnts = []
    DIR = '/Users/jonathan/Documents/CountryWiseAnalytics/'
    with open(DIR + 'UsersPerCountry.csv', 'r') as UPC:
        UsersCountry = csv.DictReader(UPC, restval=None, restkey=None, dialect='excel')
        for row in UsersCountry:
            cnt = row['Continent:']
            if cnt not in cnts:
                cnts.append(cnt)
                self.menucnt = QtGui.QMenu(self.menuCountry)
                self.menucnt.setObjectName(_fromUtf8(cnt))

Upvotes: 2

Views: 992

Answers (2)

Sadie LaBounty
Sadie LaBounty

Reputation: 379

Working answer:

Continents = {}
    CTs = {}
    popCT = ['United States', 'United Kingdom', 'South Africa', 'Germany', 'India', 'Australia', 'Canada', 'Italy', 'Sweden' ,\
    'Netherlands', 'France', 'New Zealand', 'Belgium', 'Switzerland', 'Norway', 'Brazil', 'Indonesia', 'Russia', \
    'United Arab Emirates', 'Spain', 'Denmark']
    DIR = '/Users/jonathan/Documents/CountryWiseAnalytics/'
    with open(DIR + 'UsersPerCountry.csv', 'r') as UPC:
        UsersCountry = csv.DictReader(UPC, restval=None, restkey=None, dialect='excel')
        for row in UsersCountry:
            Continent = row['Continent:']
            continentMenu = Continents.get(Continent, None)
            if continentMenu is None:
                continentMenu = self.menuCountry.addMenu(Continent)
                Continents[Continent] = continentMenu
            countryAction = continentMenu.addAction(row['Country:'])
            CT = row['Country:']
            if CT in popCT:
                self.actionCT = QtGui.QAction(self.menuPopular_Countries)
                self.actionCT.setObjectName(_fromUtf8(CT))
                CTMenu = CTs.setdefault(CT, self.menuPopular_Countries.addAction(CT))

Upvotes: 0

Laurent G
Laurent G

Reputation: 397

I would make cnts a dict, not a list ([]).

That dict would be from continent name to the QtGui.QMenu you get by self.menucnt.addMenu(cnt). It then would give you the right QMenu to add a QAction.

Something like :

cnt_menu = cnts.setdefault(cnt, self.menucnt.addMenu(cnt))
cnt_menu.addAction(row['Country:'])

cf http://pyqt.sourceforge.net/Docs/PyQt4/qmenu.html

[EDIT]

And I would not create menus and menuitems by direct calls to constructors but use the add* method from menuItem containers, giving them names I would like to see. Calling directly the constructor, just set up the memory management link, not the containment link.

Cf http://doc.qt.io/qt-4.8/objecttrees.html

By the way, are you sure you need setObjectName ?

Upvotes: 1

Related Questions