PyQt QScrollArea within QScrollArea - python

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_()

Related

PyQt5 Python Scroll area can't scroll it's content

I can't make scroll area scrolling.
Added into it QLabel and grid with 100 lines.
You can see code and screenshot bellow.
Does someone know how to add grid into scrolling area?
import sys
from PyQt5 import QtWidgets
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 960, 820)
self.setMinimumWidth(960)
self.setMinimumHeight(820)
self.user_interface()
def user_interface(self):
self.setFont(QFont('Times', 11))
# 100 lines grid
grid = QGridLayout()
for i in range(0, 100):
for j in range(0, 1):
grid.addWidget(QLabel("Hello There"), i, j)
grid.addWidget(QLabel("General Kenobi"), i, j + 1)
# scroll layout with QLabel and 100 lines grid
scroll_layout = QVBoxLayout()
scroll_layout.addWidget(QLabel("Scroll me down baby"))
scroll_layout.addLayout(grid)
scroll_layout.addStretch()
# Creation of scroll area and set scroll layout as its layout
scroll_area = QScrollArea()
scroll_area.setLayout(scroll_layout)
scroll_area.setWidgetResizable(False)
# main layout
main_layout = QtWidgets.QVBoxLayout()
main_layout.addWidget(QLabel("I stay on my place"))
main_layout.addWidget(scroll_area)
# application GUI setup
central_widget = QtWidgets.QWidget(self)
self.setCentralWidget(central_widget)
central_widget.setLayout(main_layout)
self.show()
def main():
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())
if __name__ == '__main__':
main()
Here is screenshot:
Thanks guys!
Found solution for my question ->
https://www.pythonguis.com/tutorials/qscrollarea/

PyQt5 add QScrollArea to a Frame or a Widget

I want to hide a QScrollArea which displays pages of PDF files. I know how to hide widgets and frames, and so I want to add the QScrollArea to either one of them so that it can be hidden. I tried setStyleSheet ('height:0px;'), which doesn't work.
This is the sample Code taken from https://www.learnpyqt.com/tutorials/qscrollarea/#adding%20a%20qscrollarea%20from%20code. Specific to this code how do I add self.scroll to a frame or a widget?
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic, QtMultimediaWidgets, QtWebEngineWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.Qt import *
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(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
self.pageLabel0 = QLabel()
self.pageLabel0.setAlignment(Qt.AlignCenter)
self.pageLabel0PageImage = QPixmap('pdfs/page_0.png').scaledToWidth(self.width(), Qt.SmoothTransformation)
self.pageLabel0.setPixmap(self.pageLabel0PageImage)
self.vbox.addWidget(self.pageLabel0)
self.pageLabel1 = QLabel()
self.pageLabel1.setAlignment(Qt.AlignCenter)
self.pageLabel1PageImage = QPixmap('pdfs/page_1.png').scaledToWidth(self.width(), Qt.SmoothTransformation)
self.pageLabel1.setPixmap(self.pageLabel1PageImage)
self.vbox.addWidget(self.pageLabel1)
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)
self.setGeometry(600, 100, 1000, 900)
self.setWindowTitle('Scroll Area Demonstration')
self.show()
return
def main():
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Just add self.scroll.hide() to your code.

PyQT - Add a boxlayout to a boxlayout

I would like to create a Horizontal BoxLayout and put inside a vertical BoxLayout.
I came up with the following code that does not work: my window shows up, but the BoxLayouts are not there (at least not visible):
self.setTabText(0, "Folders")
layout1 = QHBoxLayout()
l = QLabel();
l.setPixmap(QPixmap("pics/file.png"))
text = QTextEdit("Un fichier")
element = QVBoxLayout()
element.addChildWidget(l)
element.addChildWidget(text)
layout1.addChildWidget(element)
self.tab1.setLayout(layout1)
How can I make this work ?
You need to add some widget to the layout, such the widget itself can have another layout.
import sys
from PyQt4 import QtGui , QtCore
class Viewer(QtGui.QMainWindow):
def __init__(self, parent = None):
super(Viewer, self).__init__(parent)
self.centralwidget = QtGui.QWidget(self)
self.setCentralWidget(self.centralwidget)
layout1 = QtGui.QHBoxLayout()
self.centralwidget.setLayout(layout1)
l = QtGui.QLabel()
l.setPixmap(QtGui.QPixmap("folder.png"))
text = QtGui.QTextEdit("Un fichier")
element = QtGui.QWidget(self)
layout2 = QtGui.QVBoxLayout()
element.setLayout(layout2)
layout2.addWidget(l)
layout2.addWidget(text)
layout1.addWidget(element)
app = QtGui.QApplication(sys.argv)
viewer = Viewer()
viewer.show()
sys.exit(app.exec_())
For me, I usually assign another widget for the inner layout and it works.
self.setTabText(0, "Folders")
layout1 = QHBoxLayout()
l = QLabel();
l.setPixmap(QPixmap("pics/file.png"))
text = QTextEdit("Un fichier")
element = QVBoxLayout()
#widget = QWidget()
#widget.setLayout(element)
element.addWidget(l)
element.addWidget(text)
#layout1.addWidget(widget)
self.tab1.setLayout(layout1)
codes beginning with # are modified or added.

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 QVBoxLayout adding elements at bottom

I'm a beginner learning Python/PyQt.
I'm trying to add QLabel and QLineEdits to a QVBoxLayout however all the widgets get added at the bottom of the screen.
I've tried using vbox.setAlignment(Qt.AlignTop) but that does not seem to work either.
Any pointers are appreciated!
main.py
import sys
import os
from PyQt4.QtGui import *
from PyQt4.QtCore import *
app = QApplication(sys.argv)
class m_Window(QWidget):
def __init__(self, scale = 1):
QWidget.__init__(self)
self.initUI(scale)
def initUI(self, scale):
#initialize window sizes
win_width = app.desktop().screenGeometry().width() * scale
win_height = app.desktop().screenGeometry().height() * scale
#init widgets
project_name_lbl = QLabel('<b>Project Name</b>', self)
project_name_inp = QLineEdit(self)
frameworks = ['Skeleton CSS','Bootstrap','UIKit','Foundation','JQuery']
framework_cmbx = QComboBox(self)
framework_cmbx.addItems(frameworks)
#add items to layout
vbox = QVBoxLayout()
vbox.addStretch()
vbox.addWidget(project_name_lbl)
vbox.addWidget(project_name_inp)
vbox.addWidget(framework_cmbx)
#self settings
self.setLayout(vbox)
self.setWindowTitle('Website Template Maker')
self.setMinimumSize(QSize(win_width, win_height))
def run(self):
self.show()
sys.exit(app.exec_())
m_Window(.5).run()
pic:
Move the line
vbox.addStretch()
To after you've added your widgets:
vbox = QVBoxLayout()
vbox.addWidget(project_name_lbl)
vbox.addWidget(project_name_inp)
vbox.addWidget(framework_cmbx)
vbox.addStretch()
This will make the layout push your widgets up instead of down.

Categories