Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. [pyqt5 / python 3.7] How to dynamically define a ToolBar?
Forum Updated to NodeBB v4.3 + New Features

[pyqt5 / python 3.7] How to dynamically define a ToolBar?

Scheduled Pinned Locked Moved Solved Qt for Python
6 Posts 2 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • DenniD Offline
    DenniD Offline
    Denni
    wrote on last edited by Denni
    #1

    I know how to set up a toolbar based on the menu but I am trying to make the toolbar adjustable by the user which means I will have to store the layout in my database and then create it based on the query results -- so here is my test program and while it kind of works the most important part does not work as I have denoted -- this works except you will have to make an images directory and put the 3 images you want to use within it:

    import sys
    
    from PyQt5.QtCore    import *
    from PyQt5.QtGui     import *
    from PyQt5.QtWidgets import *
    
    class CenterPanel(QWidget):
        def __init__(self, MainWin):
            QWidget.__init__(self)
            self.MainWin = MainWin
    
            CntrPane = QSplitter(Qt.Horizontal, self)
            CntrPane.addWidget(QTextEdit())
            CntrPane.addWidget(QTextEdit())
            CntrPane.setSizes([75,200])
    
            hbox = QHBoxLayout(self)
            hbox.addWidget(CntrPane)
    
            self.setLayout(hbox)
    
        @property
        def MainWin(self):
            return self.__parent
    
        @MainWin.setter
        def MainWin(self, value):
            self.__parent = value
    
    class MenuToolBar(QDockWidget):
        def __init__(self, MainWin):
            QDockWidget.__init__(self)
            self.MainWin = MainWin
            self.MainMenu = MainWin.menuBar()
            
            # ******* Create the File Menu *******
            self.FileMenu  = self.MainMenu.addMenu('File')
    
            self.NewFileAct = QAction(QIcon('images/new.png'), 'New File', self)
            self.NewFileAct.setShortcut("Ctrl+N")
            self.NewFileAct.setStatusTip('Create a New Project File')
            self.NewFileAct.triggered.connect(self.NewProjFile)
    
            # ******* Create File Menu Items *******
            self.OpnFileAct = QAction(QIcon('images/open.png'), 'Open File', self)
            self.OpnFileAct.setShortcut("Ctrl+O")
            self.OpnFileAct.setStatusTip('Open an Existing Project File')
            self.OpnFileAct.triggered.connect(self.OpenProjFile)
    
            self.SavFileAct = QAction(QIcon('images/save.png'), 'Save File', self)
            self.SavFileAct.setShortcut("Ctrl+S")
            self.SavFileAct.setStatusTip('Save Current Project File')
            self.SavFileAct.triggered.connect(self.SaveProjFile)
    
            # ******* Setup the File Menu *******
            self.FileMenu.addAction(self.NewFileAct)
            self.FileMenu.addSeparator()
            self.FileMenu.addAction(self.OpnFileAct)
            self.FileMenu.addSeparator()
            self.FileMenu.addAction(self.SavFileAct)
    
            self.InitToolBar(MainWin)
    
        def InitToolBar(self, MainWin):
            # Add Items to the Toolbar
            # This needs to be dynamically based on user adjustments if any
            self.mainToolBar = MainWin.addToolBar("Quick Access")
    
    # This how I would do it normally and it works just fine
    #        self.mainToolBar.addAction(self.OpnFileAct)
    #        self.mainToolBar.addAction(self.SavFileAct)
    #        self.mainToolBar.addAction(self.NewFileAct)
    
    # Here I am trying to figure out how to load the various items dynamically if stored as follows:
    # It sort of works I just need to translate the Action string
    #
            NewToolBarLayout = {0:{'addAction': 'self.NewFileAct'},
                                1:{'addSeparator': ''},
                                2:{'addAction': 'self.OpnFileAct'},
                                3:{'addSeparator': ''},
                                4:{'addAction': 'self.SavFileAct'}}
    #
            for idx in NewToolBarLayout:
                item = NewToolBarLayout[idx]
    
                if 'addAction' in item.keys():
                    value = item['addAction']
    #               How to translate the above so that the stored 'self.OpnProjAct' string
    #               for instance becomes the same internal value it is defined as
                    self.mainToolBar.addAction(value)  
    
                elif 'addSeparator' in item.keys():
                    self.mainToolBar.addSeparator()
    #
    
        def NewProjFile(self):
            print("Added New Project File")
    
        def OpenProjFile(self):
            print("Opened Existing Project File")
    
        def SaveProjFile(self):
            print("Saved Current Project File")
    
    class Window(QMainWindow):
        def __init__(self, parent=None):
            super(Window, self).__init__(parent)
    
            self.title = 'New Project'
            self.LeftEdge  = 100
            self.TopEdge   = 100
            self.WinWidth  = 800
            self.WinHeight = 600
    
            self.setWindowTitle(self.title)
            self.setGeometry(self.LeftEdge, self.TopEdge, self.WinWidth, self.WinHeight)
            self.CenterPane = CenterPanel(self)
            self.setCentralWidget(self.CenterPane)
            self.MenuToolBar = MenuToolBar(self)
            self.setStyle(QStyleFactory.create('Cleanlooks'))
    
    if __name__ == '__main__':
        newProj = QApplication([])
    
        GUI = Window()
        GUI.show()
    
        sys.exit(newProj.exec_())
    

    madness... is like gravity, all takes is a little... push -- like from an unsolvable bug

    jsulmJ 1 Reply Last reply
    0
    • DenniD Denni

      I know how to set up a toolbar based on the menu but I am trying to make the toolbar adjustable by the user which means I will have to store the layout in my database and then create it based on the query results -- so here is my test program and while it kind of works the most important part does not work as I have denoted -- this works except you will have to make an images directory and put the 3 images you want to use within it:

      import sys
      
      from PyQt5.QtCore    import *
      from PyQt5.QtGui     import *
      from PyQt5.QtWidgets import *
      
      class CenterPanel(QWidget):
          def __init__(self, MainWin):
              QWidget.__init__(self)
              self.MainWin = MainWin
      
              CntrPane = QSplitter(Qt.Horizontal, self)
              CntrPane.addWidget(QTextEdit())
              CntrPane.addWidget(QTextEdit())
              CntrPane.setSizes([75,200])
      
              hbox = QHBoxLayout(self)
              hbox.addWidget(CntrPane)
      
              self.setLayout(hbox)
      
          @property
          def MainWin(self):
              return self.__parent
      
          @MainWin.setter
          def MainWin(self, value):
              self.__parent = value
      
      class MenuToolBar(QDockWidget):
          def __init__(self, MainWin):
              QDockWidget.__init__(self)
              self.MainWin = MainWin
              self.MainMenu = MainWin.menuBar()
              
              # ******* Create the File Menu *******
              self.FileMenu  = self.MainMenu.addMenu('File')
      
              self.NewFileAct = QAction(QIcon('images/new.png'), 'New File', self)
              self.NewFileAct.setShortcut("Ctrl+N")
              self.NewFileAct.setStatusTip('Create a New Project File')
              self.NewFileAct.triggered.connect(self.NewProjFile)
      
              # ******* Create File Menu Items *******
              self.OpnFileAct = QAction(QIcon('images/open.png'), 'Open File', self)
              self.OpnFileAct.setShortcut("Ctrl+O")
              self.OpnFileAct.setStatusTip('Open an Existing Project File')
              self.OpnFileAct.triggered.connect(self.OpenProjFile)
      
              self.SavFileAct = QAction(QIcon('images/save.png'), 'Save File', self)
              self.SavFileAct.setShortcut("Ctrl+S")
              self.SavFileAct.setStatusTip('Save Current Project File')
              self.SavFileAct.triggered.connect(self.SaveProjFile)
      
              # ******* Setup the File Menu *******
              self.FileMenu.addAction(self.NewFileAct)
              self.FileMenu.addSeparator()
              self.FileMenu.addAction(self.OpnFileAct)
              self.FileMenu.addSeparator()
              self.FileMenu.addAction(self.SavFileAct)
      
              self.InitToolBar(MainWin)
      
          def InitToolBar(self, MainWin):
              # Add Items to the Toolbar
              # This needs to be dynamically based on user adjustments if any
              self.mainToolBar = MainWin.addToolBar("Quick Access")
      
      # This how I would do it normally and it works just fine
      #        self.mainToolBar.addAction(self.OpnFileAct)
      #        self.mainToolBar.addAction(self.SavFileAct)
      #        self.mainToolBar.addAction(self.NewFileAct)
      
      # Here I am trying to figure out how to load the various items dynamically if stored as follows:
      # It sort of works I just need to translate the Action string
      #
              NewToolBarLayout = {0:{'addAction': 'self.NewFileAct'},
                                  1:{'addSeparator': ''},
                                  2:{'addAction': 'self.OpnFileAct'},
                                  3:{'addSeparator': ''},
                                  4:{'addAction': 'self.SavFileAct'}}
      #
              for idx in NewToolBarLayout:
                  item = NewToolBarLayout[idx]
      
                  if 'addAction' in item.keys():
                      value = item['addAction']
      #               How to translate the above so that the stored 'self.OpnProjAct' string
      #               for instance becomes the same internal value it is defined as
                      self.mainToolBar.addAction(value)  
      
                  elif 'addSeparator' in item.keys():
                      self.mainToolBar.addSeparator()
      #
      
          def NewProjFile(self):
              print("Added New Project File")
      
          def OpenProjFile(self):
              print("Opened Existing Project File")
      
          def SaveProjFile(self):
              print("Saved Current Project File")
      
      class Window(QMainWindow):
          def __init__(self, parent=None):
              super(Window, self).__init__(parent)
      
              self.title = 'New Project'
              self.LeftEdge  = 100
              self.TopEdge   = 100
              self.WinWidth  = 800
              self.WinHeight = 600
      
              self.setWindowTitle(self.title)
              self.setGeometry(self.LeftEdge, self.TopEdge, self.WinWidth, self.WinHeight)
              self.CenterPane = CenterPanel(self)
              self.setCentralWidget(self.CenterPane)
              self.MenuToolBar = MenuToolBar(self)
              self.setStyle(QStyleFactory.create('Cleanlooks'))
      
      if __name__ == '__main__':
          newProj = QApplication([])
      
          GUI = Window()
          GUI.show()
      
          sys.exit(newProj.exec_())
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Denni You can use https://doc.qt.io/qt-5/resources.html to embed the images with your application.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • DenniD Offline
        DenniD Offline
        Denni
        wrote on last edited by Denni
        #3

        They are just generic images no need to take up extra space my sending them hither and yon -- heck you do not even need them you just do not have a visual of the box without an image is all and the directory would still need to be set up as I cannot include that with the images (I do not think?).

        Also having looked at the Link it appears that is something you combine with the executable and what I supplied is not an executable but source code? Then again perhaps I am wrong if so please explain.

        madness... is like gravity, all takes is a little... push -- like from an unsolvable bug

        jsulmJ 1 Reply Last reply
        0
        • DenniD Denni

          They are just generic images no need to take up extra space my sending them hither and yon -- heck you do not even need them you just do not have a visual of the box without an image is all and the directory would still need to be set up as I cannot include that with the images (I do not think?).

          Also having looked at the Link it appears that is something you combine with the executable and what I supplied is not an executable but source code? Then again perhaps I am wrong if so please explain.

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Denni Then I don't understand what the problem is.
          You stated: "this works except you will have to make an images directory and put the 3 images you want to use within it". So, I thought that the problem was to provide the images along the application. If this is not the actual issue then please explain better what the issue is.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • DenniD Offline
            DenniD Offline
            Denni
            wrote on last edited by Denni
            #5

            I said "while it kind of works" ... if you had ran it you would have seen what the true issue was. I thought simply looking at the code would be sufficient my bad.

            To clarify the program works but it fails to implement the proper implementation of the toolbar. Instead of displaying the icons with their code behind trigger it shows the string of the name of that object with no code behind trigger. Note I have also included a static proper implementation of the toolbar but have re-marked it out it is there in case you want to see what I am trying to implement dynamically

            What I am attempting to do is implement the icon with code-behind trigger dynamically which means I need to be able to implement the object that contains that dynamically which is not what is occurring. I have the name of the object but as the comment states -- how do I go about converting the name of the object into the actual object and/or is there another way to go about doing this that I am not aware of.

            madness... is like gravity, all takes is a little... push -- like from an unsolvable bug

            1 Reply Last reply
            0
            • DenniD Offline
              DenniD Offline
              Denni
              wrote on last edited by Denni
              #6

              Okay a suggestion which would not work directly from someone else on a different forum got me thinking down a different path and I was able to figure out a viable solution. Granted, while it might not be as pretty of a solution as I would like it to have been, it will still work and might be the only one that would. So instead of storing a reference to the pointer to the object between instances I am hard-coding (hate doing this) a reference to the name during the creation of that object and storing these two within a dictionary. Then upon retrieving the named layout of the toolbar I use that name-reference to get my object-reference and she works just fine. Below is an edited version of the previous code with the working version in case anyone else is interested in doing this.

              import sys
              
              from PyQt5.QtCore    import *
              from PyQt5.QtGui     import *
              from PyQt5.QtWidgets import *
              
              class CenterPanel(QWidget):
                  def __init__(self, MainWin):
                      QWidget.__init__(self)
                      self.MainWin = MainWin
              
                      CntrPane = QSplitter(Qt.Horizontal, self)
                      CntrPane.addWidget(QTextEdit())
                      CntrPane.addWidget(QTextEdit())
                      CntrPane.setSizes([75,200])
              
                      hbox = QHBoxLayout(self)
                      hbox.addWidget(CntrPane)
              
                      self.setLayout(hbox)
              
                  @property
                  def MainWin(self):
                      return self.__parent
              
                  @MainWin.setter
                  def MainWin(self, value):
                      self.__parent = value
              
              class MenuToolBar(QDockWidget):
                  def __init__(self, MainWin):
                      QDockWidget.__init__(self)
                      self.MainWin = MainWin
                      self.MainMenu = MainWin.menuBar()
                      
                      self.MenuActRef = {'NewFileAct':0,
                                         'OpnFileAct':0,
                                         'SavFileAct':0}
              
                      # ******* Create the File Menu *******
                      self.FileMenu  = self.MainMenu.addMenu('File')
              
                      self.NewFileAct = QAction(QIcon('img/new.png'), 'New File', self)
                      self.NewFileAct.setShortcut("Ctrl+N")
                      self.NewFileAct.setStatusTip('Create a New Project File')
                      self.NewFileAct.triggered.connect(self.NewProjFile)
                      self.MenuActRef['NewFileAct'] = self.NewFileAct
              
                      # ******* Create File Menu Items *******
                      self.OpnFileAct = QAction(QIcon('img/open.png'), 'Open File', self)
                      self.OpnFileAct.setShortcut("Ctrl+O")
                      self.OpnFileAct.setStatusTip('Open an Existing Project File')
                      self.OpnFileAct.triggered.connect(self.OpenProjFile)
                      self.MenuActRef['OpnFileAct'] = self.OpnFileAct
              
                      self.SavFileAct = QAction(QIcon('img/save.png'), 'Save File', self)
                      self.SavFileAct.setShortcut("Ctrl+S")
                      self.SavFileAct.setStatusTip('Save Current Project File')
                      self.SavFileAct.triggered.connect(self.SaveProjFile)
                      self.MenuActRef['SavFileAct'] = self.SavFileAct
              
                      # ******* Setup the File Menu *******
                      self.FileMenu.addAction(self.NewFileAct)
                      self.FileMenu.addSeparator()
                      self.FileMenu.addAction(self.OpnFileAct)
                      self.FileMenu.addSeparator()
                      self.FileMenu.addAction(self.SavFileAct)
              
                      self.InitToolBar(MainWin)
              
                  def InitToolBar(self, MainWin):
                      # Dynamically Add Items to the Toolbar
                      self.mainToolBar = MainWin.addToolBar("Quick Access")
              
                      # This represents reading these values in via a Query
                      NewToolBarLayout = {0:'NewFileAct',
                                          1:'Spacer',
                                          2:'OpnFileAct',
                                          3:'Spacer',
                                          4:'SavFileAct'}
              
                      for idx in NewToolBarLayout:
                          item = NewToolBarLayout[idx]
              
                          if item == 'Spacer':
                              self.mainToolBar.addSeparator()
                          
                          else:
                              self.mainToolBar.addAction(self.MenuActRef[item])  
              
                  def NewProjFile(self):
                      print("Added New Project File")
              
                  def OpenProjFile(self):
                      print("Opened Existing Project File")
              
                  def SaveProjFile(self):
                      print("Saved Current Project File")
              
              class Window(QMainWindow):
                  def __init__(self, parent=None):
                      super(Window, self).__init__(parent)
              
                      self.title = 'New Project'
                      self.LeftEdge  = 100
                      self.TopEdge   = 100
                      self.WinWidth  = 800
                      self.WinHeight = 600
              
                      self.setWindowTitle(self.title)
                      self.setGeometry(self.LeftEdge, self.TopEdge, self.WinWidth, self.WinHeight)
                      self.CenterPane = CenterPanel(self)
                      self.setCentralWidget(self.CenterPane)
                      self.MenuToolBar = MenuToolBar(self)
                      self.setStyle(QStyleFactory.create('Cleanlooks'))
              
              if __name__ == '__main__':
                  newProj = QApplication([])
              
                  GUI = Window()
                  GUI.show()
              
                  sys.exit(newProj.exec_())
              

              madness... is like gravity, all takes is a little... push -- like from an unsolvable bug

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved