Results 1 to 11 of 11

Thread: best layout fo a fixed part (on the left) and a dynamic part (on the right)

  1. #1
    Join Date
    Apr 2019
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default best layout fo a fixed part (on the left) and a dynamic part (on the right)

    HI,
    I'm new in pyqt5 and I'm going to realize a GUI where on the left I have 3 buttons and on the right I could have different widgets depending on which button has been pushed.
    Scenario looks like this

    BUTTON 1 |
    BUTTON 2 | DYNAMIC AREA
    BUTTON 3 |

    In this scenario, where the left part is fixed (I'll always have the 3 buttons) and on the right I will have different widgets, which is the best layout to use?

    The grid layout?

    Thanks,
    M

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Maybe QVBoxLayout on the left side, a QStackWidget on the right side.

    Cheers,
    _

  3. #3
    Join Date
    Apr 2019
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Ok, thank you.
    If I'm not wrong, I need a parent layout that in my case could be a QHBoxLayout, which will contain a QVBoxLayout (the lest panel) and a QStackWIdget (on the right panel). Maybe I'm wrong since the QStackWidget is not a layout.
    Two more questions.
    Any time a button is click on the left panel, I have to remove all widgets in the right panel. Should I looking for any widget in the right panel and delete it one-by-one?
    May I add a vertical line between the left panel and the right one?
    Thanks for your support and patience.
    M
    Last edited by mcanonic; 16th May 2019 at 11:05.

  4. #4
    Join Date
    Jul 2008
    Location
    Germany
    Posts
    503
    Thanks
    11
    Thanked 76 Times in 74 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Hi, the QStackWidget has multiple pages, but it displays only one of these pages at a time. So instead of deleting any widgets on your right panel, you arrange your widgets on different pages (one for each button) and simply change the page of the QStackWidget when a button is clicked.

    To draw a line use QFrame with QFrame::VLine as shape, or try a QSplitter.

    Ginsengelf

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Quote Originally Posted by mcanonic View Post
    If I'm not wrong, I need a parent layout that in my case could be a QHBoxLayout, which will contain a QVBoxLayout (the lest panel) and a QStackWIdget (on the right panel).
    Right. Or a QSplitter as Ginsengelf said.

    Quote Originally Posted by mcanonic View Post
    Any time a button is click on the left panel, I have to remove all widgets in the right panel. Should I looking for any widget in the right panel and delete it one-by-one?
    May I add a vertical line between the left panel and the right one?
    Again as Ginsengelf said, the idea about using a QStackWidget is to avoid having to do that.

    Essentially you add your buttons to a QButtonGroup and use the "id" argument to associate the page index on the stack widget side with the button.
    You can then directly connect the buttongroup's buttonClicked(int) signal with the stackedwidget's setCurrentIndex(int) slot and are done.

    Cheers,
    _

  6. #6
    Join Date
    Apr 2019
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Quote Originally Posted by anda_skoa View Post
    Right. Or a QSplitter as Ginsengelf said.



    Again as Ginsengelf said, the idea about using a QStackWidget is to avoid having to do that.

    Essentially you add your buttons to a QButtonGroup and use the "id" argument to associate the page index on the stack widget side with the button.
    You can then directly connect the buttongroup's buttonClicked(int) signal with the stackedwidget's setCurrentIndex(int) slot and are done.

    Cheers,
    _
    Dear Anda_Skoa,
    your suggestions seems very interesting and I tried to implement it with no luck. For now, I just skiped the QButtonGroup suggestion and I was focusing in the QStackWidget. So, in the main screen I have a left panel with a QVBoxLayout and on the right panel I have a QStackedWidget:

    Qt Code:
    1. def UI(self):
    2. mainScreen=QHBoxLayout()
    3.  
    4. leftPanel = QVBoxLayout()
    5. #rightPanel = QVBoxLayout()
    6. rightPanel = QStackedWidget()
    7.  
    8. line = QtWidgets.QFrame()
    9. line.setGeometry(QtCore.QRect(213, 20, 20, 391))
    10. line.setFrameShape(QtWidgets.QFrame.VLine)
    11. line.setFrameShadow(QtWidgets.QFrame.Sunken)
    12. line.setObjectName("line")
    13.  
    14. self.loadLeftPanel(leftPanel)
    15. self.loadRightPanel(rightPanel)
    16.  
    17. mainScreen.addLayout(leftPanel)
    18. mainScreen.addWidget(line)
    19. mainScreen.addLayout(rightPanel)
    20.  
    21.  
    22. rightPanel.setCurrentIndex(1)
    23.  
    24. self.setLayout(mainScreen)
    25. self.show()
    To copy to clipboard, switch view to plain text mode 

    Now the problem is in the "loadRightPanel" function. Looking at some example I have to add some widget (one for each page), provide a function for the UI specific for each stack and finally add the widget at the layout. This is what I did:
    Qt Code:
    1. def loadRightPanel(rightPanel):
    2. stack1 =QWidget()
    3. stack2 =QWidget()
    4. #stack3 =QWidget()
    5.  
    6. stack1UI(stack1)
    7. stack2UI(stack2)
    8. #stack3UI()
    9.  
    10. rightPanel.addWidget(stack1)
    11. rightPanel.addWidget(stack2)
    12. #rightPanel.addWidget(stack3)
    To copy to clipboard, switch view to plain text mode 

    and the UI for each stack looks like this:
    Qt Code:
    1. def stack1UI(self,stack1):
    2. layout1 = QVBoxLayout()
    3. welcomeText1 = QLabel("STACK1 - Android Forensic Automator (AnForA)", self)
    4. welcomeText1.setAlignment(Qt.AlignCenter)
    5. welcomeText1.setFont(QtGui.QFont("Times", 12, QtGui.QFont.Bold))
    6. welcomeText2 = QLabel("a software tool that automates the forensic analysis of Android applications", self)
    7. welcomeText2.setFont(QtGui.QFont("Times", 12))
    8. layout1.addStretch(1)
    9. layout1.addWidget(welcomeText1)
    10. layout1.addWidget(welcomeText2)
    11. layout1.addStretch(1)
    12. stack1.setLayout(layout1)
    To copy to clipboard, switch view to plain text mode 

    but something is wrong and I'm little confuse.
    Could you help me out, please?
    M

  7. #7
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    The only thing that looks outright wrong is this line

    Qt Code:
    1. mainScreen.addLayout(rightPanel)
    To copy to clipboard, switch view to plain text mode 
    rightPanel is a QStackedWidget so it needs to be added with addWidget()
    Qt Code:
    1. mainScreen.addWidget(rightPanel)
    To copy to clipboard, switch view to plain text mode 

    I would also recommend to do the stack pages as separate classes, makes the code much more maintainable

    Qt Code:
    1. class WelcomePage(QWidget)
    2.  
    3.  
    4. ....
    5.  
    6.  
    7. stack1 = WelcomePage()
    8. rightPanel.addWidget(stack1)
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  8. #8
    Join Date
    Apr 2019
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Thank you Ada, your suggestion are precious.
    Now I have a class for each page as you suggested.

    I'm missing one last step to ask, if you (or/and other in this forum) have more patience.

    The leftPanel has buttons and by click on some button, I have to chage the page on rightPanel.

    So when I load the left panel, I need a button able to use rightPanel.setCurrentIndex(1).

    The code is like this:
    Qt Code:
    1. def loadLeftPanel(self,leftPanel,rightPanel):
    2. ...
    3. installAPKBtn = QPushButton("Install APK on the device", self)
    4. ...
    5. leftPanel.addWidget(installAPKBtn)
    6.  
    7. installAPKBtn.clicked.connect(self.installAPK())
    8.  
    9. def installAPK(self):
    10. self.rightPanel.setCurrentIndex(1)
    To copy to clipboard, switch view to plain text mode 

    I think I need something like: installAPKBtn.clicked.connect(self.installAPK(righ tPanel))
    but my various attempt did not work

    Any idea?

    Thanks,
    M


    Added after 8 minutes:


    In the meanwhile, I read about lambda:

    installAPKBtn.clicked.connect(lambda:self.installA PK(rightPanel))

    def installAPK(self, rightPanel):
    rightPanel.setCurrentIndex(1)

    is this the right way to manage these problem?

    Thanks again,
    M
    Last edited by mcanonic; 31st May 2019 at 17:59.

  9. #9
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Quote Originally Posted by mcanonic View Post
    So when I load the left panel, I need a button able to use rightPanel.setCurrentIndex(1).
    Right, or using a QButtonGroup

    Quote Originally Posted by mcanonic View Post
    I think I need something like: installAPKBtn.clicked.connect(self.installAPK(righ tPanel))
    Not necessarily. Your code should work fine if self.rightPanel exists, i.e. if rightPanel is a member variable of your class.

    Quote Originally Posted by mcanonic View Post
    In the meanwhile, I read about lambda:

    installAPKBtn.clicked.connect(lambda:self.installA PK(rightPanel))

    def installAPK(self, rightPanel):
    rightPanel.setCurrentIndex(1)

    is this the right way to manage these problem?
    Yes, this is also an option. The lambda can even call setCurrentIndex directly.

    Cheers,
    _

  10. #10
    Join Date
    Apr 2019
    Posts
    13
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Thank you! I'm almost done.
    This should be my last question.

    As you suggested, I wrote the code with QButtonGroup like this:
    Qt Code:
    1. def loadLeftPanel(self,leftPanel,rightPanel):
    2. #Create QButtonGroup
    3. btnGrp = QButtonGroup(self)
    4. btnGrp.setExclusive(True)
    5. btnGrp.addButton(installAPKBtn,1)
    6. btnGrp.addButton(detectPathBtn,2)
    7. btnGrp.addButton(startExpBtn,3)
    8. btnGrp.addButton(analyzeResBtn,4)
    9. btnGrp.addButton(quitBtn,5)
    10.  
    11.  
    12. btnGrp.buttonClicked.connect(self.onClick)
    13.  
    14. def onClick(self,btn):
    15. rightPanel.setCurrentIndex(id)
    To copy to clipboard, switch view to plain text mode 

    Now the problem is this: onClick has the object relative to the button that was pressed, but I need to know the id not the button object. As you can see, I add the button by specify as second parameter the id, but I'm not able to retreive it.

    Any idea how can I fix this?

    Thanks,
    M


    Added after 1 41 minutes:


    Quote Originally Posted by mcanonic View Post
    Thank you! I'm almost done.
    This should be my last question.

    As you suggested, I wrote the code with QButtonGroup like this:
    Qt Code:
    1. def loadLeftPanel(self,leftPanel,rightPanel):
    2. #Create QButtonGroup
    3. btnGrp = QButtonGroup(self)
    4. btnGrp.setExclusive(True)
    5. btnGrp.addButton(installAPKBtn,1)
    6. btnGrp.addButton(detectPathBtn,2)
    7. btnGrp.addButton(startExpBtn,3)
    8. btnGrp.addButton(analyzeResBtn,4)
    9. btnGrp.addButton(quitBtn,5)
    10.  
    11.  
    12. btnGrp.buttonClicked.connect(self.onClick)
    13.  
    14. def onClick(self,btn):
    15. rightPanel.setCurrentIndex(id)
    To copy to clipboard, switch view to plain text mode 

    Now the problem is this: onClick has the object relative to the button that was pressed, but I need to know the id not the button object. As you can see, I add the button by specify as second parameter the id, but I'm not able to retreive it.

    Any idea how can I fix this?

    Thanks,
    M
    In the meanwhile, I've put btnGrp as a global value (I know this is bad, but I just want to see how it works) and I have modified the onClick method like this:
    Qt Code:
    1. def onClick(self,btn):
    2. print('Text of the pressed btn '+btn.text())
    3. print('id of the pressed btn '+str(btnGrp.checkedId()))
    To copy to clipboard, switch view to plain text mode 

    The text is correct but not the id: it is alway equals to -1.

    I cannot see where my code is wrong.
    Thanks for your help.
    M
    Last edited by mcanonic; 3rd June 2019 at 16:56.

  11. #11
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: best layout fo a fixed part (on the left) and a dynamic part (on the right)

    Quote Originally Posted by mcanonic View Post
    Now the problem is this: onClick has the object relative to the button that was pressed, but I need to know the id not the button object. As you can see, I add the button by specify as second parameter the id, but I'm not able to retreive it.
    The problem is that there are two buttonClicked() signals, one with a button and one with an ID as the argument.

    Try this
    Qt Code:
    1. btnGrp.buttonClicked[int].connect(self.onClick)
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

Similar Threads

  1. Reading text file line part by part
    By anh5kor in forum Newbie
    Replies: 4
    Last Post: 23rd December 2015, 12:31
  2. Part of QString
    By arturs in forum Newbie
    Replies: 1
    Last Post: 18th July 2015, 17:27
  3. QToolBar Layout(when part of QMainWindow)
    By iridium in forum Qt Programming
    Replies: 3
    Last Post: 18th April 2013, 14:19
  4. Replies: 6
    Last Post: 16th April 2013, 17:13
  5. Replies: 2
    Last Post: 23rd August 2011, 13:23

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.