How to display Qframe as actual size in PyQt5? - python

Here is My program. My Requirement: Display frame as mentioned size. But in my code its occupies the entire area. How to resolve it?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class FrameExample(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frame Example")
self.setGeometry(100,100,1500,900)
self.frame = QFrame()
self.frame.resize(300, 300)
self.frame.setStyleSheet("background-color:skyblue")
self.frame1 = QFrame()
self.frame1.setGeometry(QRect(10,10,600,600))
self.frame1.resize(600,600)
self.frame1.setStyleSheet("background-color:lightgreen")
layout = QVBoxLayout()
layout.addWidget(self.frame)
layout.addWidget(self.frame1)
self.setLayout(layout)
if __name__=="__main__":
app = QApplication(sys.argv)
countrywin =FrameExample()
countrywin.show()
sys.exit(app.exec_())

With resize() you are managing the size of the widget but after setting the layouts it will handle the size. One possible solution is to use setFixedSize():
class FrameExample(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frame Example")
self.setGeometry(100, 100, 1500, 900)
self.frame = QFrame()
self.frame.setFixedSize(300, 300)
self.frame.setStyleSheet("background-color:skyblue")
self.frame1 = QFrame()
self.frame1.setFixedSize(600, 600)
self.frame1.setStyleSheet("background-color:lightgreen")
layout = QVBoxLayout(self)
layout.addWidget(self.frame)
layout.addWidget(self.frame1)

Related

PyQt5 add a scrollbar to main window

I know there are already lots of threads opened with this topic, I was trying to follow their recommendations, but I still struggle to achieve this.
Here is my initial code for window:
from PyQt5.QtWidgets import *
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Python ")
self.setGeometry(100, 100, 600, 400)
self.UiComponents()
self.show()
def UiComponents(self):
emphysemaLabel = QLabel("EMPHYSEMA", self)
emphysemaLabel.move(10, 10)
ggoLabel = QLabel("GGO", self)
ggoLabel.move(10, 300)
condensLabel = QLabel("Condens", self)
condensLabel.move(10, 590)
emphysema_graph_lin = QLabel(self)
emphysema_graph_lin.resize(302, 232)
emphysema_graph_lin.move(10, 50)
emphysema_graph_lin.setStyleSheet("background-color:yellow;")
ggo_graph_lin = QLabel(self)
ggo_graph_lin.resize(302, 232)
ggo_graph_lin.move(10, 340)
ggo_graph_lin.setStyleSheet("background-color:yellow;")
condens_graph_lin = QLabel(self)
condens_graph_lin.resize(302, 232)
condens_graph_lin.move(10, 630)
condens_graph_lin.setStyleSheet("background-color:yellow;")
if __name__ == "__main__":
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
An example if what I found useful and working is code found here https://www.pythonguis.com/tutorials/qscrollarea/
I tried to apply it to my code, like this:
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Python ")
self.setGeometry(100, 100, 600, 400)
self.UiComponents()
self.show()
def UiComponents(self):
self.scroll = QScrollArea() # Scroll Area which contains the widgets, set as the centralWidget
self.widget = QWidget() # Widget that contains the collection of Vertical Box
self.vbox = QVBoxLayout() # The Vertical Box that contains the Horizontal Boxes of labels and buttons
emphysemaLabel = QLabel("EMPHYSEMA", self)
emphysemaLabel.move(10, 10)
self.vbox.addWidget(emphysemaLabel)
ggoLabel = QLabel("GGO", self)
ggoLabel.move(10, 300)
self.vbox.addWidget(ggoLabel)
condensLabel = QLabel("Condens", self)
condensLabel.move(10, 590)
self.vbox.addWidget(condensLabel)
emphysema_graph_lin = QLabel(self)
emphysema_graph_lin.resize(302, 232)
emphysema_graph_lin.move(10, 50)
emphysema_graph_lin.setStyleSheet("background-color:yellow;")
self.vbox.addWidget(emphysema_graph_lin)
ggo_graph_lin = QLabel(self)
ggo_graph_lin.resize(302, 232)
ggo_graph_lin.move(10, 340)
ggo_graph_lin.setStyleSheet("background-color:yellow;")
self.vbox.addWidget(ggo_graph_lin)
condens_graph_lin = QLabel(self)
condens_graph_lin.resize(302, 232)
condens_graph_lin.move(10, 630)
condens_graph_lin.setStyleSheet("background-color:yellow;")
self.vbox.addWidget(condens_graph_lin)
self.widget.setLayout(self.vbox)
# Scroll Area Properties
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
if __name__ == "__main__":
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())
But it's not working, how should I do it?
Thank you for any advice.
You can add a vertical spacer at the end of the layout using the addStretch() method of the QVBoxLayout object.
And adjust the maximum size to view the scroll working, setMaximumSize().
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
import sys
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Python ")
self.setGeometry(100, 100, 600, 400)
# set maximum size of the QMainWindow
self.setMaximumSize(600, 100)
self.UiComponents()
self.show()
def UiComponents(self):
self.scroll = QScrollArea() # Scroll Area which contains the widgets, set as the centralWidget
self.widget = QWidget() # Widget that contains the collection of Vertical Box
self.vbox = QVBoxLayout() # The Vertical Box that contains the Horizontal Boxes of labels and buttons
emphysemaLabel = QLabel("EMPHYSEMA", self)
emphysemaLabel.move(10, 10)
self.vbox.addWidget(emphysemaLabel)
ggoLabel = QLabel("GGO", self)
ggoLabel.move(10, 300)
self.vbox.addWidget(ggoLabel)
condensLabel = QLabel("Condens", self)
condensLabel.move(10, 590)
self.vbox.addWidget(condensLabel)
emphysema_graph_lin = QLabel(self)
emphysema_graph_lin.resize(302, 232)
emphysema_graph_lin.move(10, 50)
emphysema_graph_lin.setStyleSheet("background-color:yellow;")
self.vbox.addWidget(emphysema_graph_lin)
ggo_graph_lin = QLabel(self)
ggo_graph_lin.resize(302, 232)
ggo_graph_lin.move(10, 340)
ggo_graph_lin.setStyleSheet("background-color:yellow;")
self.vbox.addWidget(ggo_graph_lin)
condens_graph_lin = QLabel(self)
condens_graph_lin.resize(302, 232)
condens_graph_lin.move(10, 630)
condens_graph_lin.setStyleSheet("background-color:yellow;")
self.vbox.addWidget(condens_graph_lin)
# add a vertical spacer with addStretch() method
self.vbox.addStretch()
self.widget.setLayout(self.vbox)
# Scroll Area Properties
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.widget)
self.setCentralWidget(self.scroll)
if __name__ == "__main__":
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec())

How do I modify spacing in nested PyQt layouts?

Currently, I have a nested QVBoxLayout in the first column of a QHBoxLayout, but no matter my changes to .setContentMargins or .setSpacing nothing changes in that first column.
import sys
import io
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
class MyApp(QWidget):
def __init__(self):
super().__init__()
# Main widget/window
self.setWindowTitle('Test')
self.window_width, self.window_height = 1600, 900
self.setMinimumSize(self.window_width, self.window_height)
layout = QHBoxLayout()
self.setLayout(layout)
leftside = QWidget()
leftlayout = QVBoxLayout()
# Creating textbox and adding to leftside GUI
lineEdit = QLineEdit()
leftlayout.addWidget(lineEdit)
leftlayout.addWidget(QPushButton('Placeholder'))
leftside.setLayout(leftlayout)
# Adding both widgets to main layout
testWidget = QWidget()
testWidget.setStyleSheet("background-color: blue")
layout.addWidget(leftside, 2)
layout.addWidget(testWidget, 8)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyleSheet('''
QWidget {
font-size: 20px;
}
''')
myApp = MyApp()
myApp.show()
try:
sys.exit(app.exec_())
except SystemExit:
print('Closing Window...')
Leaves me with this result:
What I want:
Use addStretch() method:
class MyApp(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Test")
self.window_width, self.window_height = 1600, 900
self.setMinimumSize(self.window_width, self.window_height)
leftside = QWidget()
leftlayout = QVBoxLayout(leftside)
lineEdit = QLineEdit()
leftlayout.addWidget(lineEdit)
leftlayout.addWidget(QPushButton("Placeholder"))
leftlayout.addStretch()
testWidget = QWidget()
testWidget.setStyleSheet("background-color: blue")
layout = QHBoxLayout(self)
layout.addWidget(leftside)
layout.addWidget(testWidget, stretch=1)

How to control the proportions of a QFrame in a layout?

It's My Code. My Requirement: if the Window Grows the frame also expands as per ratio in both directions. I am trying with SetSize Policy, but nothing will happen. How to achieve it?
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class FrameExample(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frame Example")
self.setGeometry(100,100,600,600)
self.frame = QFrame()
self.frame.setFixedSize(200,200)
# self.frame.setSizePolicy(QSizePolicy.Minimum,QSizePolicy.Fixed)
self.frame.setStyleSheet("background-color:skyblue")
self.frame1 = QFrame()
self.frame1.setGeometry(QRect(10,10,600,600))
self.frame1.resize(600,600)
self.frame1.setStyleSheet("background-color:lightgreen")
layout = QVBoxLayout()
layout.addWidget(self.frame)
layout.addWidget(self.frame1)
self.setLayout(layout)
if __name__=="__main__":
app = QApplication(sys.argv)
countrywin =FrameExample()
countrywin.show()
sys.exit(app.exec_())
From the comments, it appears you want the top frame to get a third of the width (i.e. 200/600 == 1/3), with the height remaining fixed - but it should not resize smaller than the minimum in either direction. Meanwhile, the bottom frame should just take up whatever space is left over.
This can be achieved by firstly setting the minimum-size and an appropriate size-policy on the top frame. Its proportions can then be controlled by putting it in a horizontal layout and adding stretchers with appropriate stretch factors (depending on how the frame should be aligned).
Here is a working example based on your code:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class FrameExample(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Frame Example")
self.setGeometry(100, 100, 600, 600)
self.frame = QFrame()
self.frame.setStyleSheet("background-color:skyblue")
self.frame.setMinimumSize(QSize(200, 200))
self.frame.setSizePolicy(
QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
hbox = QHBoxLayout()
# align left
hbox.addWidget(self.frame, 1)
hbox.addStretch(2)
# align centre
# hbox.addStretch()
# hbox.addWidget(self.frame)
# hbox.addStretch()
self.frame1 = QFrame()
self.frame1.setStyleSheet("background-color:lightgreen")
layout = QVBoxLayout()
layout.addLayout(hbox)
layout.addWidget(self.frame1)
self.setLayout(layout)
if __name__=="__main__":
app = QApplication(sys.argv)
countrywin =FrameExample()
countrywin.show()
sys.exit(app.exec_())

Dynamically resize buttons in a Pyside GUI and manage Layouts

I have read the documentation on the following matter, but QtGui is so overwhelmingly complex I might have missed the piece.
I have created a GUI, in which it consists of a menubar two QLabel and two QLineEdit and a button. The issue I am facing in my code is the button is getting placed on an absolute co-ordinate position and does not dynamically resize according to the window resizing and the QLineEdit box is displayed with a certain horizontal shift from the QLabel. But I would like to place it next to the QLabel. I have attached a pic of the GUI which I am getting. Here is my code
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class guiwindow(QMainWindow):
def __init__(self):
super(guiwindow,self).__init__()
self.central = QWidget()
self.setCentralWidget(self.central)
self.setGeometry(400, 100, 1200, 800)
self.setWindowTitle(" Automatic Selector")
self.menubar()
self.makebuttons()
self.angles()
def menubar(self):
textEdit = QWidget()
self.setCentralWidget(textEdit)
exitAction = QAction('Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(self.close)
self.statusBar()
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAction)
def makebuttons(self):
# self.central_widget = QWidget()
# self.setCentralWidget(self.central_widget)
button = QPushButton("Test", self)
hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(button)
# self.central_widget.setLayout(hbox)
self.show()
def angles(self):
self.window = QWidget()
self.setCentralWidget(self.window)
self.Rotation = QLabel('Rotation:')
self.Tilt = QLabel('Tilt:')
self.RotationEdit = QLineEdit()
self.RotationEdit.setFixedWidth(55)
self.TiltEdit = QLineEdit()
self.TiltEdit.setFixedWidth(55)
self.grid = QGridLayout()
self.grid.addWidget(self.Rotation,1,0,Qt.AlignLeft)
self.grid.addWidget(self.RotationEdit,1,1,Qt.AlignLeft)
self.grid.addWidget(self.Tilt,2,0,Qt.AlignLeft)
self.grid.addWidget(self.TiltEdit, 2,1,Qt.AlignLeft)
self.window.setLayout(self.grid)
def main():
app = QApplication(sys.argv)
ex = guiwindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
And if I take out
self.window = QWidget()
self.setCentralWidget(self.window)
from the def angles(self): the Rotation angle and the tilt angle does not appear on the GUI. Why does this

PyQt QScrollArea within QScrollArea

I am trying to use multiple horizontal sub QScrollAreas with text and one vertical container QScrollArea. The idea being that the text area in the horizontal sub QScrollAreas will always have equivalent vertical heights and I would like to have one vertical QScrollArea to control the data within them.
The code below shows that the horizontal sub QScrollAreas work, but the vertical QScrollArea doesn't detect that the line edits within the widget inside it don't fit vertically. If I change
scroll.setWidgetResizable(True)
for the vertical QScrollArea to False, the vertical QScrollArea detects the widget inside doesn't fit but I want to be able to scroll all the lineEdits up and down not the parent widget. Also I would like all scrollbars to be always visible. Is this possible?
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Widget(QWidget):
def __init__(self, parent= None):
super(Widget, self).__init__()
self.setGeometry(100, 100, 400, 400)
baseWidget = QWidget()
hBox = QHBoxLayout()
hBox.addWidget(self.getWidget())
hBox.addWidget(self.getWidget())
baseWidget.setLayout(hBox)
scroll = QScrollArea()
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
#when set to False all scrolls are not visible and can only scroll parent widget not the data areas
scroll.setWidgetResizable(True)
scroll.setWidget(baseWidget)
vBox = QHBoxLayout()
vBox.addWidget(scroll)
self.setLayout(vBox)
def getWidget(self):
widget = QWidget()
layout = QVBoxLayout()
for i in range(20):
lineEdit = QLineEdit("row: "+str(i)+" data: "+str(list(range(10))))
lineEdit.setMinimumWidth(250)
layout.addWidget(lineEdit)
widget.setLayout(layout)
scroll = QScrollArea()
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll.setWidgetResizable(False)
scroll.setWidget(widget)
return scroll
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Widget()
dialog.show()
The answer could be found here:
PyQt4 : is there any signal related to scrollbar?
Just needed to sync vertical scrollbars and hide all but one:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Widget(QWidget):
def __init__(self, parent= None):
super(Widget, self).__init__()
self.setGeometry(100, 100, 200, 200)
baseWidget = QWidget()
hBox = QHBoxLayout()
lscrollArea = self.getWidget(False)
rScrollArea = self.getWidget(True)
rScrollArea.verticalScrollBar().valueChanged.connect(
lscrollArea.verticalScrollBar().setValue)
hBox.addWidget(lscrollArea)
hBox.addWidget(rScrollArea)
baseWidget.setLayout(hBox)
vBox = QHBoxLayout()
vBox.addWidget(baseWidget)
self.setLayout(vBox)
def getWidget(self, vScrollOn):
widget = QWidget()
layout = QVBoxLayout()
for i in range(20):
lineEdit = QLineEdit("row: "+str(i)+" data: "+str(list(range(10))))
lineEdit.setMinimumWidth(250)
layout.addWidget(lineEdit)
widget.setLayout(layout)
scroll = QScrollArea()
if vScrollOn:
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
else:
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll.setWidgetResizable(False)
scroll.setWidget(widget)
return scroll
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Widget()
dialog.show()
app.exec_()

Categories