Posts: 53
Threads: 18
Joined: Nov 2016
A lot of people seem to have this problem. How do I get a QScrollArea to scroll. I have this code below that creates widgets and places them in lines in a QScrollArea to display information. I need to set 4 widgest per line and space them out properly to display all the needed information. The problem in I cant get the ScrollArea to scroll.
(Using PyQt5)
self.pkg_display = QtWidgets.QScrollArea(self)
self.pkg_display.setGeometry(10, 40, 801, 401)
self.pkg_display.setStyleSheet("background-color: White")
self.pkg_display.setVerticalScrollBarPolicy(2)
self.pkg_display.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(0, 0, 801, 800)
self.pkg_display.setWidget(self.scrollAreaWidgetContents) def update_list():
pos = 0
x1 = 10
y1 = 2
x2 = 393
y2 = 5
x3 = 700
x4 = 756
for i in filtered_name:
cb = QtWidgets.QCheckBox(ui.scrollAreaWidgetContents)
cb.setGeometry(x1,y1,361,23)
cb.setText(i)
vtext = QtWidgets.QLabel(ui.scrollAreaWidgetContents)
vtext.setGeometry(x2,y2,291,17)
vtext.setText(filtered_version[pos])
stext = QtWidgets.QLabel(ui.scrollAreaWidgetContents)
stext.setGeometry(x3,y2,51,17)
stext.setText(filtered_size[pos])
ib = QtWidgets.QPushButton(ui.scrollAreaWidgetContents)
ib.setGeometry(x4,y1,21,21)
ib.setText("i")
y1 += 23
y2 += 23
pos += 1
ui.pkg_display.update() The code creates the widjets and places them in the ScrollArea(pkg_dsiplay), but it will not scroll.
If anyone is wondering I am working on a tool to replace dnfdrogora(A Linux graphical package manager tool)
Posts: 1,027
Threads: 16
Joined: Dec 2016
Nobody can really help with a few snippets of code.
Example PyQt5 GUI Creating QScrollArea
Posts: 53
Threads: 18
Joined: Nov 2016
(Oct-22-2021, 08:08 PM)Axel_Erfurt Wrote: Nobody can really help with a few snippets of code.
Example PyQt5 GUI Creating QScrollArea
Here is a full example of how I am creating the the window, scrollarea, and widgets.
import sys
import subprocess
from PyQt5 import QtWidgets
filtered_name = []
filtered_version = []
filtered_size = []
app = QtWidgets.QApplication(sys.argv)
class MyWindow(QtWidgets.QMainWindow):
def setup(self):
QtWidgets.QMainWindow.__init__(self)
self.resize(820, 625)
self.setWindowTitle("PkgMgr")
self.setMaximumSize(820, 620)
self.setMinimumSize(16, 9)
self.uninstallB = QtWidgets.QPushButton(self)
self.uninstallB.setGeometry(10, 10, 111, 25)
self.uninstallB.setText("Uninstall")
self.clear_selectB = QtWidgets.QPushButton(self)
self.clear_selectB.setGeometry(130, 10, 111, 25)
self.clear_selectB.setText("Clear Selection")
self.searchB = QtWidgets.QPushButton(self)
self.searchB.setGeometry(620, 10, 91, 25)
self.searchB.setText("Search")
self.clear_searchB = QtWidgets.QPushButton(self)
self.clear_searchB.setGeometry(720, 10, 91, 25)
self.clear_searchB.setText("Clear Search")
self.search_bar = QtWidgets.QLineEdit(self)
self.search_bar.setGeometry(450, 10, 161, 25)
self.pkg_display = QtWidgets.QScrollArea(self)
self.pkg_display.setGeometry(10, 40, 801, 401)
self.pkg_display.setStyleSheet("background-color: White")
self.pkg_display.setVerticalScrollBarPolicy(2)
self.pkg_display.setWidgetResizable(True)
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(0, 0, 801, 800)
self.pkg_display.setWidget(self.scrollAreaWidgetContents)
self.info_display = QtWidgets.QTextBrowser(self)
self.info_display.setGeometry(10, 450, 801, 161)
def get_package(mode):
cmd = subprocess.Popen("dnf info -C --installed", shell=True, stdout=subprocess.PIPE)
raw_out = cmd.stdout.readlines()
vpos = 0
for l in raw_out:
l = str(l)
size = l.find("b'Size")
name = l.find("b'Name")
version = l.find("b'Version")
release = l.find("b'Release")
if name != -1:
line = l[name+17:len(l)-3]
filtered_name.append(line)
elif version != -1:
line = l[version+17:len(l)-3]
filtered_version.append(line)
elif release != -1:
line = l[release+17:len(l)-3]
filtered_version[vpos] += "-" + line
vpos += 1
elif size != -1:
line = l[size+17:len(l)-3]
filtered_size.append(line)
def update_list():
pos = 0
x1 = 10
y1 = 2
x2 = 393
y2 = 5
x3 = 700
x4 = 756
for l in filtered_name:
cb = QtWidgets.QCheckBox(ui.scrollAreaWidgetContents)
cb.setGeometry(x1,y1,361,23)
cb.setText(l)
vtext = QtWidgets.QLabel(ui.scrollAreaWidgetContents)
vtext.setGeometry(x2,y2,291,17)
vtext.setText(filtered_version[pos])
stext = QtWidgets.QLabel(ui.scrollAreaWidgetContents)
stext.setGeometry(x3,y2,51,17)
stext.setText(filtered_size[pos])
ib = QtWidgets.QPushButton(ui.scrollAreaWidgetContents)
ib.setGeometry(x4,y1,21,21)
ib.setText("i")
y1 += 23
y2 += 23
pos += 1
ui.pkg_display.update()
ui = MyWindow()
ui.setup()
get_package(0)
update_list()
ui.show()
sys.exit(app.exec_())
Posts: 6,779
Threads: 20
Joined: Feb 2020
I cannot run your example (I have PySide2) and translating to PySide2 is difficult because of how you use the designer (which I hate hate hate hate designer code).
This is a short example of a working scrollable area.
import sys
import PySide2.QtWidgets as QtWidgets
from PySide2.QtCore import Qt
class MyWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.view = QtWidgets.QWidget()
self.layout = QtWidgets.QVBoxLayout(self.view)
self.scroll = QtWidgets.QScrollArea(self)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.view)
self.setCentralWidget(self.scroll)
for i in range(20):
self.layout.addWidget(QtWidgets.QLabel('Make this a fairly wide Label '+str(i)))
app = QtWidgets.QApplication(sys.argv)
ui = MyWindow()
ui.show()
sys.exit(app.exec_()) The important parts are that the scrolled widget is larger than the scrollable area and that the scrollable area knows how big the scrolled widget is (setWidgetResizeable(True)).
Looking at your example I think the problem is that the scrolled widget is not larger than the scrollable area. I'm guessing that ui.scrollAreaWidgetContents is your scrolled widget (a QWidget?). I see where you place things in this widget but I don't see where the widget is resized. I would stop using setGeometry and use a layout manager instead. That will automatically grow the scrolled widget as needed.
Posts: 1,027
Threads: 16
Joined: Dec 2016
Why don't you just use a QTableWidget with checkboxes?
Here is a simple example (for apt, since I use mint)
import sys
import subprocess
from PyQt5 import QtWidgets, QtCore
filtered_name = []
filtered_version = []
filtered_size = []
app = QtWidgets.QApplication(sys.argv)
class MyWindow(QtWidgets.QMainWindow):
def setup(self):
QtWidgets.QMainWindow.__init__(self)
self.resize(820, 625)
self.setWindowTitle("PkgMgr")
self.setMaximumSize(820, 620)
self.setMinimumSize(16, 9)
self.table = QtWidgets.QTableWidget()
self.table.setColumnCount(3)
self.table.setHorizontalHeaderLabels(["", "Name", "Version"])
self.setCentralWidget(self.table)
def get_package(self, mode):
cmd = subprocess.Popen("apt list --installed", shell=True, stdout=subprocess.PIPE)
raw_out = cmd.stdout.readlines()
for l in raw_out[1:]:
name = l.decode().partition("/")[0]
version = l.decode().partition("/")[2].partition(",now ")[2]
print(name, version)
filtered_name.append(name)
filtered_version.append(version)
def update_list(self):
for x in range(len(filtered_name)):
self.table.insertRow(x)
item = QtWidgets.QTableWidgetItem('uninstall')
item.setFlags(QtCore.Qt.ItemIsUserCheckable |
QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Unchecked)
self.table.setItem(x, 0, item)
self.table.setItem(x, 1, QtWidgets.QTableWidgetItem(filtered_name[x]))
self.table.setItem(x, 2, QtWidgets.QTableWidgetItem(filtered_version[x]))
self.table.resizeColumnsToContents()
ui = MyWindow()
ui.setup()
ui.get_package(0)
ui.update_list()
ui.show()
sys.exit(app.exec_())
Posts: 53
Threads: 18
Joined: Nov 2016
Oct-24-2021, 07:29 PM
(This post was last modified: Oct-24-2021, 08:10 PM by LavaCreeperKing.)
"The important parts are that the scrolled widget is larger than the scrollable area and that the scrollable area knows how big the scrolled widget is (setWidgetResizeable(True))."
But when I do self.scrollAreaWidgetContents.setGeometry(0, 0, 801, 800) or self.scrollAreaWidgetContents.resize(801,800) is that not making it larger than pkg_display(self.pkg_display.setGeometry(10, 40, 801, 401)? The problem I have with layout managers is I can't control where my widgets are placed or how big/small they are.
@ Axel_Erfurt
Yes I could do that, but this the effect that I wanted to achieve.
EDIT: So I just removed self.pkg_display.setWidgetResizable(True) from my code... and now my scroll area works just fine.
Posts: 1,027
Threads: 16
Joined: Dec 2016
Using setGeometry is not a good idea. A BoxLayout (HBox, VBox) or GridLayout is better.
Posts: 6,779
Threads: 20
Joined: Feb 2020
I agree that setGeometry is a bad idea. Your example is easily achieved using a grid layout manager.
Posts: 53
Threads: 18
Joined: Nov 2016
Oct-28-2021, 09:07 PM
(This post was last modified: Oct-28-2021, 09:08 PM by LavaCreeperKing.)
(Oct-26-2021, 08:05 PM)deanhystad Wrote: I agree that setGeometry is a bad idea. Your example is easily achieved using a grid layout manager.
Then could you please give me an example? I don't know how to use layout managers.
Posts: 1,027
Threads: 16
Joined: Dec 2016
Oct-29-2021, 08:33 AM
(This post was last modified: Oct-29-2021, 08:33 AM by Axel_Erfurt.)
|