Qscrollbar in PyQt5 nothing is shown - python

I need to add info of students (it looks like a table) to the window. It's done in a function called "addStudentStats" and it's added to a main widget. I was trying to make another widget insert scrollbar, and this widget insert into a main one. But it didn't work. Then i tried to make the whole window scrollable, but i couldn't do it either. If anyone can can write those few lines of code (i think there are few, but don't know which) i would be pleased.
Read here
I've added a scrollbar to my window. The program fills it with data, which goes down the screen, but i cannot scroll
from PyQt5.QtWidgets import QPushButton, QWidget, QLabel,QScrollArea, QApplication, QMainWindow
from PyQt5.QtCore import Qt
import sys
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.uiMain = UIMainTeacher()
self.setUpUI(self)
def setUpUI(self, MainWindow):
MainWindow.setGeometry(50, 50, 400, 450)
MainWindow.setFixedSize(1800, 1000)
MainWindow.setWindowTitle("Login")
self.uiMain = UIMainTeacher()
self.gotoTeacher()
def gotoTeacher(self):
self.uiMain.setupUI(self, type)
self.show()
class UIMainTeacher(object):
def setupUI(self, MainWindow, userId):
MainWindow.setGeometry(50, 50, 400, 450)
MainWindow.setFixedSize(1800, 1000)
MainWindow.setWindowTitle("Main")
self.mainWindow = MainWindow
self.centralwid = QScrollArea(MainWindow)
self.centralwid.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.centralwidget = QWidget(self.centralwid)
self.exitButton = QPushButton("Exit", self.centralwid)
self.exitButton.move(1700, 0)
self.CourseLabel = QLabel("No Kourse yet", self.centralwid)
self.CourseLabel.move(900, 20)
self.AddCourseButton = QPushButton('Add Course', self.centralwid)
self.AddCourseButton.move(1700, 25)
self.CourseLabel = QLabel("Course", self.centralwidget)
self.CourseLabel.move(900, 20)
self.AddStudentsButton = QPushButton("Add Students", self.centralwid)
self.AddStudentsButton.move(1700, 100)
self.taskLabel = QLabel("TASKS:", self.centralwidget)
self.taskLabel.move(160, 20)
self.AddTaskButton = QPushButton('Add Task', self.centralwid)
self.AddTaskButton.move(1700, 50)
self.centralwid.setWidget(self.centralwidget)
MainWindow.setCentralWidget(self.centralwid)
x, y = 600, 0
for _ in range(200):
label = QLabel("Test Test", self.centralwid)
label.move(x, y)
y += 50
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())

The problem is simple QScrollArea is a container that serves to show another widget that has a large size, and that widget is what you pass through the setWidget() method. QScrollArea calculates the necessary size using the sizeHint() of the widget, so in your case the one that is caudding the problem is that widget since its sizeHint() is 0, 0. Why is it 0, 0? because it has nothing inside since the labels are children of the QScrollArea and not the widget, and even if it did not have the sizeHint() since there are at least 2 ways to calculate them: the layout gives you that information but in your case you use it, and the second is to set a fixed size to the widget, and that is the solution I have chosen, I do not know if it is what you want since I do not know what type of output you want, but you can see that the QScrollArea is visible.
class UIMainTeacher(object):
def setupUI(self, MainWindow):
MainWindow.setGeometry(50, 50, 400, 450)
MainWindow.setFixedSize(1800, 1000)
MainWindow.setWindowTitle("Main")
self.mainWindow = MainWindow
self.centralwid = QScrollArea(MainWindow)
self.centralwid.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.centralwidget = QWidget(self.centralwid)
self.exitButton = QPushButton("Exit", self.centralwid)
self.exitButton.move(1700, 0)
self.CourseLabel = QLabel("No Kourse yet", self.centralwid)
self.CourseLabel.move(900, 20)
self.AddCourseButton = QPushButton('Add Course', self.centralwid)
self.AddCourseButton.move(1700, 25)
self.CourseLabel = QLabel("Course", self.centralwidget)
self.CourseLabel.move(900, 20)
self.AddStudentsButton = QPushButton("Add Students", self.centralwid)
self.AddStudentsButton.move(1700, 100)
self.taskLabel = QLabel("TASKS:", self.centralwidget)
self.taskLabel.move(160, 20)
self.AddTaskButton = QPushButton('Add Task', self.centralwid)
self.AddTaskButton.move(1700, 50)
self.centralwid.setWidget(self.centralwidget)
MainWindow.setCentralWidget(self.centralwid)
x, y = 600, 0
for _ in range(200):
label = QLabel("Test Test", self.centralwidget)
label.move(x, y)
y += 50
self.centralwidget.setFixedWidth(800)
self.centralwidget.setFixedHeight(y)
so if you are going to add more elements you will have to calculate and set the setFixedHeight(), another option is to use layouts but since I do not know what design you expect I will not be able to provide you with that second solution.

Related

pyside/pyqt how to animate an arc simply?

I'm looking for a solution, to animate this arc from 0 - 360°. I'm relative new to Pyside/Pyqt and I don't find such a simple solution (only beginner "unfriedly"). I tried it with while loops aswell, but it doesn't works. At the moment I don't understand this animation system, but I want to work on it.
import sys
from PySide6 import QtCore
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtCore import Qt
from PySide6.QtGui import QBrush, QPen, QPainter
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("AnimateArc")
self.setGeometry(100, 100, 600, 600)
def paintEvent(self, event):
self.anim = QtCore.QPropertyAnimation(self, b"width", duration=1000) #<- is there a documentation for b"width", b"geometry"?
self.anim.setStartValue(0)
start = 0
painter = QPainter(self)
painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
painter.drawArc(100, 100, 400, 400, 90 * 16, start * 16) # I want to make the change dynamicly
self.anim.setEndValue(360)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()
QPropertyAnimation is used to animate Qt properties of any QObject. If you refer to self (the current instance of QMainWindow), then you can animate all properties of a QMainWindow and all inherited properties (QMainWindow inherits from QWidget, so you can animate all the QWidget properties as well).
In your case, you're trying to animate the width property of the window, and that's certainly not what you want to do.
Since what you want to change is a value that is not a property of the window, you cannot use QPropertyAnimation (unless you create a Qt property using the #Property decorator), and you should use a QVariantAnimation instead.
Then, a paintEvent is called by Qt every time the widget is going to be drawn (which can happen very often), so you cannot create the animation there, otherwise you could end up with a recursion: since the animation would require a repaint, you would create a new animation everytime the previous requires an update.
Finally, consider that painting on a QMainWindow is normally discouraged, as a Qt main window is a special kind of QWidget intended for advanced features (menus, status bar, etc) and uses a central widget to show the actual contents.
The correct approach is to create and set a central widget, and implement the painting on that widget instead.
Here is a revised and working version of your code:
class ArcWidget(QWidget):
def __init__(self):
super().__init__()
self.anim = QtCore.QVariantAnimation(self, duration=1000)
self.anim.setStartValue(0)
self.anim.setEndValue(360)
self.anim.valueChanged.connect(self.update)
self.anim.start()
def paintEvent(self, event):
painter = QPainter(self)
painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
painter.drawArc(
100, 100, 400, 400, 90 * 16, self.anim.currentValue() * 16)
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("AnimateArc")
self.setGeometry(100, 100, 600, 600)
self.arcWidget = ArcWidget()
self.setCentralWidget(self.arcWidget)
The valueChanged connection ensures that everytime the value changes the widget schedules an update (thus calling a paintEvent as soon as the event queue allows it), then you can use the current value of the animation to draw the actual arc.
Thanks #musicamante for the solution regarding animating arc using QAnimationProperty
Modified #musicmante code to create a loading effect guess it will help developers and might save their time who are trying to make loading effect using Qt
Source
#!/usr/bin/env python3.10
import sys
import string
import random
from PySide6.QtWidgets import (QMainWindow, QPushButton, QVBoxLayout,
QApplication, QWidget)
from PySide6.QtCore import (Qt, QVariantAnimation)
from PySide6.QtGui import (QPen, QPainter, QColor)
class Arc:
colors = list(string.ascii_lowercase[0:6]+string.digits)
shades_of_blue = ["#7CB9E8","#00308F","#72A0C1", "#F0F8FF",
"#007FFF", "#6CB4EE", "#002D62", "#5072A7",
"#002244", "#B2FFFF", "#6F00FF", "#7DF9FF","#007791",
"#ADD8E6", "#E0FFFF", "#005f69", "#76ABDF",
"#6A5ACD", "#008080", "#1da1f2", "#1a1f71", "#0C2340"]
shades_of_green = ['#32CD32', '#CAE00D', '#9EFD38', '#568203', '#93C572',
'#8DB600', '#708238', '#556B2F', '#014421', '#98FB98', '#7CFC00',
'#4F7942', '#009E60', '#00FF7F', '#00FA9A', '#177245', '#2E8B57',
'#3CB371', '#A7F432', '#123524', '#5E8C31', '#90EE90', '#03C03C',
'#66FF00', '#006600', '#D9E650']
def __init__(self):
self.diameter = random.randint(100, 600)
#cols = list(Arc.colors)
#random.shuffle(cols)
#_col = "#"+''.join(cols[:6])
#print(f"{_col=}")
#self.color = QColor(_col)
#self.color = QColor(Arc.shades_of_blue[random.randint(0, len(Arc.shades_of_blue)-1)])
self.color = QColor(Arc.shades_of_green[random.randint(0, len(Arc.shades_of_green)-1)])
#print(f"{self.color=}")
self.span = random.randint(40, 150)
self.direction = 1 if random.randint(10, 15)%2 == 0 else -1
self.startAngle = random.randint(40, 200)
self.step = random.randint(100, 300)
class ArcWidget(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.arcs = [Arc() for i in range(random.randint(10, 20))]
self.startAnime()
def initUI(self):
#self.setAutoFillBackground(True)
self.setAttribute(Qt.WA_StyledBackground, True)
self.setStyleSheet("background-color:black;")
def startAnime(self):
self.anim = QVariantAnimation(self, duration = 2000)
self.anim.setStartValue(0)
self.anim.setEndValue(360)
self.anim.valueChanged.connect(self.update)
self.anim.start()
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
#painter.setPen(QPen(QColor("#b6faec"), 5, Qt.SolidLine))
#painter.drawArc(
# 100, 100, 400, 400, 90*16,
# self.anim.currentValue() * 16)
#width = 400
#height = 400
#painter.drawArc(self.width()/2 -width/2, self.height()/2 - height/2, 400, 400, self.anim.currentValue()*16, 45*16)
for arc in self.arcs:
painter.setPen(QPen(arc.color, 6, Qt.SolidLine))
painter.drawArc(self.width()/2 - arc.diameter/2,
self.height()/2 - arc.diameter/2, arc.diameter,
arc.diameter, self.anim.currentValue()*16*arc.direction+arc.startAngle*100, arc.span*16)
#print(f"currentValue : {self.anim.currentValue()}")
#arc.startAngle = random.randint(50, 200)
if self.anim.currentValue() == 360:
#print("360")
self.startAnime()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Animate Arc")
self.setGeometry(100, 100, 600, 600)
self.arcWidget = ArcWidget()
self.setCentralWidget(self.arcWidget)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
app.exec()
output:
$ ./arc_widget.py

Absolute Position Widgets

Very confused, I've viewed multiple other stack overflow pages:
class launcherWidget( QMainWindow ) :
def __init__(self) :
QMainWindow.__init__(self)
self.setWindowTitle("Scouting Software Launcher")
#self.setGeometry(100, 100, 100, 100)
self.table = QTableWidget()
self.table.setColumnCount(3)
self.table.setHorizontalHeaderLabels(["Save Name", "Mod Date","Creation Date"])
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
#self.layout = QHBoxLayout()
#self.layout.addWidget(self.table)
#self.setLayout(self.layout)
self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.table.verticalHeader().setVisible(False)
self.fill_table_with_list([["savename","mod date","creat"],["c","b","a"]])
#self.table.resize(100,100)
self.table.setGeometry( QRect( 50, 50, 100, 100 ) )
#self.table.move(50,50)
#self.show()
self.b0 = QPushButton("New")
self.b0.clicked.connect(self.newClicked)
#self.layout.addWidget(self.b0,)
#self.b0.move(0,0)
self.b1 = QPushButton("Rename")
self.b1.clicked.connect(self.renameClicked)
#self.layout.addWidget(self.b1)
#self.b1.move(300,500)
def newClicked(self) :
print("placeholder")
def renameClicked(self):
r = self.table.currentRow()
savename = str( self.table.item(r,0).text() )
def fill_table_with_list (self, data=[[]]) :
for row in reversed(data) :
saveName = QTableWidgetItem(row[0])
modDate = QTableWidgetItem(row[1])
creaDate =QTableWidgetItem(row[2])
self.table.insertRow(0)
self.table.setItem(0, 0, saveName)
self.table.setItem(0, 1, modDate)
self.table.setItem(0, 2, creaDate)
#Slot()
def exit_app(self, checked):
QApplication.quit()
def onLaunch () :
app = QApplication(sys.argv)
window = launcherWidget() # screen = before change
#window.resize(500, 300) #can always be fullscreened
window.resize(1820,980)
window.show()
sys.exit(app.exec_())
if __name__ == "__main__":
onLaunch()
Trying to use absolute positioning and I can't get my table to show up, All I get is a blank window with nothing in it. I'd prefer to not have to use a layout, but so far that seems like the only way to get the table and buttons to show up. All the things I've commented out are attempts at making it work. table.show() seems to just show the table in a separate window. .move() seems to do nothing and recently tried setGeometry() which also doesn't work. I haven't even tried getting the buttons to show up yet, I can't imagine I'd get a different result. I first assumed I just had the cordinates wrong, but I've gone through trial and error to rule that one out
TL; DR; Pass as a parent of the widgets to the window
A widget is drawn on another widget if it is the son of the widget, in your case neither the QTableWidget nor the QPushButton, in the case of layouts apart from handling the position and size they also establish as the parent of the widgets that it handles to the widget where it is settled down.
class launcherWidget(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("Scouting Software Launcher")
self.table = QTableWidget(self)
self.table.setColumnCount(3)
self.table.setHorizontalHeaderLabels(["Save Name", "Mod Date", "Creation Date"])
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.table.verticalHeader().setVisible(False)
self.fill_table_with_list([["savename", "mod date", "creat"], ["c", "b", "a"]])
self.table.setGeometry(QRect(50, 50, 100, 100))
self.b0 = QPushButton("New", self)
self.b0.clicked.connect(self.newClicked)
self.b0.move(0,0)
self.b1 = QPushButton("Rename", self)
self.b1.clicked.connect(self.renameClicked)
self.b1.move(300,500)
# ...

All the widgets disappear when window size is decreased

When I decrease the window size all the widgets disappear.I want the widgets to move along when size is decreased.How do I solve this problem?
I have a drop-down menu from which a value is selected.When an "Add cmd" button is pressed the value is added to edit box.
Thanks in advance.
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class tabdemo(QTabWidget):
def __init__(self, parent = None):
super(tabdemo, self).__init__(parent)
self.setGeometry(50, 50, 400,400)
QShortcut(QKeySequence("Esc"), self, self.close)
self.tab1 = QWidget()
self.tab2 = QWidget()
self.addTab(self.tab1,"Tab 1")
self.tab1UI()
self.setWindowTitle("Main Window")
def tab1UI(self):
self.comboBox = QComboBox(self.tab1)
self.comboBox.addItem('ABC')
self.comboBox.addItem('BCD')
self.comboBox.addItem('CDE')
self.comboBox.move(5,20)
self.comboBox.resize(180,30)
self.button = QPushButton('Add Cmd', self.tab1)
self.button.move(190,20)
self.button.resize(80,30)
self.button.clicked.connect(self.handleTest)
self.b = QTextEdit(self.tab1)
self.b.move(20,75)
self.b.resize(290,200)
self.button = QPushButton('Send Batch', self.tab1)
self.button.move(40,300)
self.button.resize(150,30)
self.button = QPushButton('Clear', self.tab1)
self.button.move(200,300)
self.button.resize(80,30)
self.button.clicked.connect(self.deletevalue)
layout = QFormLayout()
self.setTabText(4,"BatchCMDS")
self.tab1.setLayout(layout)
def handleTest(self):
self.b.append(str(self.comboBox.currentText()))
def deletevalue(self):
self.b.clear()
def main():
app = QApplication(sys.argv)
ex = tabdemo()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
If you want the widgets to adapt to the size of the window you should use layouts, For this, the application must be designed, for this an image is used of how you want your application to be:
As we see the widgets that are inside a tab are divided into 3 groups, the first is made up of the QComboBox with the QPushButton, the second the QTextEdit, and the third the 2 remaining buttons. Each group is horizontally distributed, so in that case we should use QHBoxLayout except the QTextEdit that is alone, and each group should be in QVBoxLayout. I do not understand why you use the QFormLayout, also if you use the layouts the positions are not necessary.
Another error that I see in your code is that several buttons have the same name, this causes errors like for example that the Add CMD button does not work, you must give a different name to each widget.
class tabdemo(QTabWidget):
def __init__(self, parent = None):
super(tabdemo, self).__init__(parent)
self.setGeometry(50, 50, 400,400)
QShortcut(QKeySequence("Esc"), self, self.close)
self.tab1 = QWidget()
self.tab2 = QWidget()
self.addTab(self.tab1,"Tab 1")
self.addTab(self.tab2,"Tab 2")
self.tab1UI()
def tab1UI(self):
vlayout = QVBoxLayout(self.tab1)
hlayout1 = QHBoxLayout()
self.comboBox = QComboBox(self.tab1)
self.comboBox.addItems(['ABC', 'BCD', 'CDE'])
self.button = QPushButton('Add Cmd', self.tab1)
self.button.clicked.connect(self.handleTest)
hlayout1.addWidget(self.comboBox)
hlayout1.addWidget(self.button)
hlayout1.addItem(QSpacerItem(100, 10, QSizePolicy.Expanding, QSizePolicy.Preferred))
vlayout.addLayout(hlayout1)
self.b = QTextEdit(self.tab1)
vlayout.addWidget(self.b)
hlayout2 = QHBoxLayout()
self.buttonSend = QPushButton('Send Batch', self.tab1)
self.buttonClear = QPushButton('Clear', self.tab1)
self.buttonClear.clicked.connect(self.deletevalue)
hlayout2.addItem(QSpacerItem(100, 10, QSizePolicy.Expanding, QSizePolicy.Preferred))
hlayout2.addWidget(self.buttonSend)
hlayout2.addWidget(self.buttonClear)
hlayout2.addItem(QSpacerItem(100, 10, QSizePolicy.Expanding, QSizePolicy.Preferred))
vlayout.addLayout(hlayout2)
self.setTabText(4,"BatchCMDS")
def handleTest(self):
self.b.append(self.comboBox.currentText())
def deletevalue(self):
self.b.clear()

PyQt5 QWidget.setGeometry() not working for QLabel

I'm working on a very simple app in PyQt5 for displaying and sorting images. I'm new to Python and Qt in particular, and I've been having a few problems. I'm trying to display QPixmap images within QLabel objects, and they display properly. However, they're lined up in a row as default and I can't figure out how to move them.
(I know the code is terrible but I'm trying to get it working before I make it clean.)
Here is my code:
class ImageClassifier(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
hbox = QtWidgets.QHBoxLayout(self)
mainImg = QPixmap("img.png")
xmplImg0 = QPixmap("img0.png")
xmplImg1 = QPixmap("img1.png")
xmplImg2 = QPixmap("img2.png")
xmplImg3 = QPixmap("img3.png")
lbl = QtWidgets.QLabel(self)
lbl0 = QtWidgets.QLabel(self)
lbl1 = QtWidgets.QLabel(self)
lbl2 = QtWidgets.QLabel(self)
lbl3 = QtWidgets.QLabel(self)
lbl.setPixmap(mainImg)
lbl0.setPixmap(xmplImg0)
lbl1.setPixmap(xmplImg1)
lbl2.setPixmap(xmplImg2)
lbl3.setPixmap(xmplImg3)
hbox.addWidget(lbl)
hbox.addWidget(lbl0)
hbox.addWidget(lbl1)
hbox.addWidget(lbl2)
hbox.addWidget(lbl3)
lbl0.setGeometry(30, 30, 30, 30)
self.setLayout(hbox)
self.move(300, 200)
self.setWindowTitle('Fruit Classifier')
self.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ic = ImageClassifier()
sys.exit(app.exec_())
The lbl0.setGeometry() function isn't doing anything at all and I don't have a clue why. Does anyone know of a way to fix this, or a better way to set the position of a QLabel object?
Follow the following bullets.
When you add something to a QHBoxLayout/QVBoxLayout... you also have to set the geometry of your BoxLayout as well, not just of one element inside it.
Everything you throw inside a BoxLayout it will adjust to it's parent(BoxLayout).
Try setting the geometry of all your elements.
Try setting the geometry of your BoxLayout
If still doesn't work try setting ".setFixedSize(_width,_height)" also for all elements & BoxLayout, as you need.
[Update]
Look what I'm trying to say. Better with a example:
If you use a BoxLayout the position of your objects won't obey what you want. It will follow the BoxLayout policy. You also passed (self) for the QLabels what makes the QWidget its parent. That's a mess.
Check it out the following code.
I have no BoxLayout and I just said who is my(Qlabel)'s parent. So I'll behave as my "daddy" says. So now you can move it along.
import sys
from PyQt5 import QtWidgets
class ImageClassifier(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setFixedSize(500,500)
lbl = QtWidgets.QLabel(self)
lbl.setFixedSize(50,50)
lbl0 = QtWidgets.QLabel(self)
lbl0.setFixedSize(50, 50)
lbl1 = QtWidgets.QLabel(self)
lbl1.setFixedSize(50, 50)
lbl2 = QtWidgets.QLabel(self)
lbl2.setFixedSize(50, 50)
lbl3 = QtWidgets.QLabel(self)
lbl3.setFixedSize(50, 50)
lbl.setStyleSheet("""background-color: red;""")
lbl0.setStyleSheet("""background-color: green;""")
lbl1.setStyleSheet("""background-color: blue;""")
lbl2.setStyleSheet("""background-color: yellow;""")
lbl3.setStyleSheet("""background-color: black;""")
lbl0.move(50,50)
lbl1.move(100, 100)
lbl2.move(150, 150)
lbl3.move(150, 150)
self.move(300, 200)
self.setWindowTitle('Fruit Classifier')
self.show()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ic = ImageClassifier()
sys.exit(app.exec_())
That's just a simple way to do it. You better create your own Label that inherit QLabel. And personalize as you wish.

How can I add scrollbars to a widget with painted lines?

I am having trouble getting this to work the way I want. I want to draw a number of lines below each other and display this in a window that has scrollbars.
So far I can draw the lines and display them, but my scrollbars wont work. What is the correct way to do this?
The file y.list contains simple pairs of numbers as start and end point of my lines. Like:
1 100
4 64
72 98
Here is my code so far:
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Example(QWidget):
def __init__(self):
super(Example, self).__init__()
def paintEvent(self, e):
qp = QPainter()
qp.begin(self)
self.drawLines(qp)
qp.end()
def drawLines(self, qp):
wTotal = 4*2*117
pen = QPen(QColor(100, 200, 0), 5, Qt.SolidLine)
qp.setPen(pen)
qp.drawLine(24, 20, 24+wTotal, 20)
pen = QPen(QColor(0, 0, 255), 2, Qt.SolidLine)
qp.setPen(pen)
qp.drawLine(24+wTotal/2,18,24+wTotal/2,22)
pen = QPen(QColor(0, 50, 255), 2, Qt.SolidLine)
qp.setPen(pen)
with open("y.list", 'r') as points:
linecount = 0
for line in points:
linecount += 1
splitLine = line.split()
start = int(splitLine[0])*4
end = int(splitLine[1])*4
qp.drawLine(20+start, 20+5*linecount, 20+end, 20+5*linecount)
class Widget(QWidget):
def __init__(self, parent= None):
super(Widget, self).__init__()
self.setGeometry(200,100,1100,800)
#Container Widget
widget = QWidget()
#Layout of Container Widget
layout = QVBoxLayout(self)
lines = Example()
layout.addWidget(lines)
widget.setLayout(layout)
#Scroll Area Properties
scroll = QScrollArea()
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll.setWidgetResizable(True)
scroll.setWidget(widget)
#Scroll Area Layer add
vLayout = QVBoxLayout(self)
vLayout.addWidget(scroll)
self.setLayout(vLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Widget()
dialog.show()
app.exec_()
Currently, you have made the widget resizable, so the widget will be automatically resized to fit the available space, and the scrollbars will never change (because they're not needed).
To change this, you need give the widget a specific size, and don't automatically resize it:
scroll.setWidgetResizable(False)
scroll.setWidget(widget)
widget.resize(2000, 2000)
NB: don't attempt to programmatically resize the widget during the paint-event, because resizing can itself cause a re-paint.

Categories