Python Forum
[PyQt] Is there a better way of laying out my GUI?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyQt] Is there a better way of laying out my GUI?
#1
I have created a simple GUI using PyQt5. However, I can't seem to find a a good way to arange my widgets. I tried groups but with my current code, I would have groups inside of groups, which starts to get confusing - it also doesn't give me that much control over where I place my widgets.
This is what I have so far:
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Settings():
    SCENE_SIZE_X = 1200
    SCENE_SIZE_Y = 900
    GRID_COUNT_X = 4
    GRID_COUNT_Y = 5
    GRID_BOX_WIDTH = 10
    GRID_BOX_HEIGHT = 10

class Grid(QtWidgets.QGraphicsScene):

    def __init__(self):
        super().__init__()

        self.lines = []
        self.initUI()

    def initUI(self):
        self.draw_grid()
        self.set_opacity(1.0)

    def draw_grid(self):
        width = Settings.GRID_COUNT_X * Settings.GRID_BOX_WIDTH
        height = Settings.GRID_COUNT_Y * Settings.GRID_BOX_HEIGHT
        self.setSceneRect(0, 0, width, height)
        self.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex)

        pen = QPen(QColor(255,0,255), 1, Qt.SolidLine)

        for x in range(0,Settings.GRID_COUNT_X+1):
            xc = x * Settings.GRID_BOX_WIDTH
            self.lines.append(self.addLine(xc,0,xc,height,pen))

        for y in range(0,Settings.GRID_COUNT_Y+1):
            yc = y * Settings.GRID_BOX_HEIGHT
            self.lines.append(self.addLine(0,yc,width,yc,pen))

    def set_opacity(self,opacity):
        for line in self.lines:
            line.setOpacity(opacity)

class ShowGrid(QtWidgets.QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.createGridLayout()
        
        gridLayout = QHBoxLayout()
        gridLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(gridLayout)

    def createGridLayout(self):
        self.horizontalGroupBox = QGroupBox("Board")

        layout = QGridLayout()
        layout.addWidget(QtWidgets.QGraphicsView(Grid()))
        self.horizontalGroupBox.setLayout(layout)

class ShowDice(QtWidgets.QWidget):
    
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.createGridLayout()
        
        gridLayout = QVBoxLayout()
        gridLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(gridLayout)

    def createGridLayout(self):
        self.horizontalGroupBox = QGroupBox("Roll Dice")

        layout = QGridLayout()
        layout.setColumnStretch(0, 1)
        layout.addWidget(QPushButton('Roll'),0,1)
        self.horizontalGroupBox.setLayout(layout)

class App(QtWidgets.QDialog):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 100, Settings.SCENE_SIZE_X, Settings.SCENE_SIZE_Y)

        self.createGridLayout()
        
        gridLayout = QVBoxLayout()
        gridLayout.addWidget(self.horizontalGroupBox)
        self.setLayout(gridLayout)

    def createGridLayout(self):
        self.horizontalGroupBox = QGroupBox("")

        layout = QGridLayout()
        layout.addWidget(ShowGrid(),0,1)
        layout.addWidget(ShowDice(),1,0)
        self.horizontalGroupBox.setLayout(layout)    
        

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle("Fusion")
    ex = App()
    ex.show()
    #scene.resize(Settings.SCENE_SIZE_X,Settings.SCENE_SIZE_Y)
    sys.exit(app.exec_())
And if it is run then you get this:
   
which looks messy because it has groups in groups and isn't arranged neatly. What is the best way to arrange these widgets (and others in the future) so I have lots of control over where they are placed?

Thanks,
Dream

edit: corrections

This is my new code, slightly improved:
import sys
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class Settings():
    SCENE_SIZE_X = 1200
    SCENE_SIZE_Y = 900
    GRID_COUNT_X = 4
    GRID_COUNT_Y = 5
    GRID_BOX_WIDTH = 100
    GRID_BOX_HEIGHT = 100

class Grid(QtWidgets.QGraphicsScene):

    def __init__(self):
        super().__init__()

        self.lines = []
        self.scrolled = 0
        self.initUI()

    def initUI(self):
        self.draw_grid(Settings.GRID_COUNT_X, Settings.GRID_COUNT_Y, Settings.GRID_BOX_WIDTH, Settings.GRID_BOX_HEIGHT)
        self.set_opacity(1.0)

    def draw_grid(self, x_count, y_count, x_size, y_size):
        width = x_count * x_size
        height = y_count * y_size
        self.setSceneRect(0, 0, width, height)
        self.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex)

        pen = QPen(QColor(0,0,0), 1, Qt.SolidLine)

        for x in range(0,x_count+1):
            xc = x * x_size
            self.lines.append(self.addLine(xc,0,xc,height,pen))
 
        for y in range(0,y_count+1):
            yc = y * y_size
            self.lines.append(self.addLine(0,yc,width,yc,pen))

    def set_opacity(self,opacity):
        for line in self.lines:
            line.setOpacity(opacity)

    def delete_grid(self):
        for line in self.lines:
            self.removeItem(line)
        del self.lines[:]

    def wheelEvent(self,event):
        self.scrolled += event.delta()/90
        if(self.scrolled > -30.0):
            self.delete_grid()
            self.draw_grid(Settings.GRID_COUNT_X, Settings.GRID_COUNT_Y, Settings.GRID_BOX_WIDTH + self.scrolled, Settings.GRID_BOX_HEIGHT + self.scrolled)
        else:
            self.scrolled = -30.0
            
class App(QtWidgets.QDialog):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 100, Settings.SCENE_SIZE_X, Settings.SCENE_SIZE_Y)

        layout = QVBoxLayout()
        layout.addWidget(QtWidgets.QGraphicsView(Grid()))
        layout.addWidget(QtWidgets.QPushButton("Hello!"))
        self.setLayout(layout)
        


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    app.setStyle("Fusion")
    ex = App()
    ex.show()
    sys.exit(app.exec_())
It still runs, I just don't know how to position these elements.
Reply


Messages In This Thread
Is there a better way of laying out my GUI? - by DreamingInsanity - May-02-2019, 05:25 PM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020