I am developing an app for memorizing text using PyQt4. I want to show all the words in bubbles so that you see how long the word is. But when I have all the bubbles in my QScrollArea
, they are aligned one under the other. I would like to have them aligned side-by-side, but with word-wrap.
I got the bubbles to work using a QLabel
with rounded borders. But now that I have the words in QLabel's
, PyQt doesn't consider them as words - but as widgets. So PyQt puts one widget under the other. I would like the widgets to be aligned side-by-side until they reach the end of the line, and then they should wrap around to the next line - meaning the QLabel's
should act like words in a text document.
Here is my code so far:
f = open(r'myFile.txt')
class Bubble(QtGui.QLabel):
def __init__(self, text):
super(Bubble, self).__init__(text)
self.word = text
self.setContentsMargins(5, 5, 5, 5)
def paintEvent(self, e):
p = QtGui.QPainter(self)
p.setRenderHint(QtGui.QPainter.Antialiasing,True)
p.drawRoundedRect(0,0,self.width()-1,self.height()-1,5,5)
super(Bubble, self).paintEvent(e)
class MainWindow(QtGui.QMainWindow):
def __init__(self, text, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.MainArea = QtGui.QScrollArea
self.widget = QtGui.QWidget()
vbox = QtGui.QVBoxLayout()
self.words = []
for t in re.findall(r'\b\w+\b', text):
label = Bubble(t)
label.setFont(QtGui.QFont('SblHebrew', 18))
label.setFixedWidth(label.sizeHint().width())
self.words.append(label)
vbox.addWidget(label)
self.widget.setLayout(vbox)
self.MainArea.setWidget(self.widget)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
myWindow = MainWindow(f.read(), None)
myWindow.show()
sys.exit(app.exec_())
When I run this I get:
But I would like the words (the Qlabel's
containing the words) to be next to each other, not under each other, like this (photoshopped):
I've been doing a lot of research, but no answers help me align the widgets next to each other.
Here's a PyQt5 version of the Flow Layout demo script:
I thought it might be possible to use html in a
QTextBrowser
widget for this, but Qt's rich-text engine doesn't support theborder-radius
CSS property which would be needed for the bubble labels.So it looks like you need a PyQt port of the Flow Layout example. This can "word-wrap" a collection of widgets inside a container, and also allows the margins and horizontal/vertical spacing to be adjusted.
Here is a demo script that implements the
FlowLayout
class and shows how to use it with your example: