gpt4 book ai didi

python - PyQt:QScrollArea 内小部件的环绕式布局

转载 作者:行者123 更新时间:2023-11-27 23:11:56 25 4
gpt4 key购买 nike

我正在开发一个使用 PyQt4 来内存文本的应用程序。我想在气泡中显示所有单词,以便您看到单词的长度。但是当我的 QScrollArea 中有所有气泡时,它们会一个接一个对齐。我想让它们并排对齐,但要自动换行。

我使用带有圆角边框的 QLabel 让气泡起作用。但是现在我在 QLabel's 中有了单词,PyQt 不会将它们视为单词 - 而是作为小部件。所以 PyQt 将一个小部件放在另一个小部件下面。我希望小部件并排对齐,直到它们到达行尾,然后它们应该环绕到下一行 - 这意味着 QLabel's 应该像文本中的单词一样文档。

到目前为止,这是我的代码:

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

当我运行它时,我得到:

picture of my example that I do not like

但我希望单词(包含单词的Qlabel)彼此相邻,而不是彼此下方,像这样(照片处理):

enter image description here

我进行了大量研究,但没有任何答案可以帮助我将小部件彼此对齐。

最佳答案

这是流布局演示脚本的 PyQt5 版本:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class FlowLayout(QtWidgets.QLayout):
def __init__(self, parent=None, margin=-1, hspacing=-1, vspacing=-1):
super(FlowLayout, self).__init__(parent)
self._hspacing = hspacing
self._vspacing = vspacing
self._items = []
self.setContentsMargins(margin, margin, margin, margin)

def __del__(self):
del self._items[:]

def addItem(self, item):
self._items.append(item)

def horizontalSpacing(self):
if self._hspacing >= 0:
return self._hspacing
else:
return self.smartSpacing(
QtWidgets.QStyle.PM_LayoutHorizontalSpacing)

def verticalSpacing(self):
if self._vspacing >= 0:
return self._vspacing
else:
return self.smartSpacing(
QtWidgets.QStyle.PM_LayoutVerticalSpacing)

def count(self):
return len(self._items)

def itemAt(self, index):
if 0 <= index < len(self._items):
return self._items[index]

def takeAt(self, index):
if 0 <= index < len(self._items):
return self._items.pop(index)

def expandingDirections(self):
return QtCore.Qt.Orientations(0)

def hasHeightForWidth(self):
return True

def heightForWidth(self, width):
return self.doLayout(QtCore.QRect(0, 0, width, 0), True)

def setGeometry(self, rect):
super(FlowLayout, self).setGeometry(rect)
self.doLayout(rect, False)

def sizeHint(self):
return self.minimumSize()

def minimumSize(self):
size = QtCore.QSize()
for item in self._items:
size = size.expandedTo(item.minimumSize())
left, top, right, bottom = self.getContentsMargins()
size += QtCore.QSize(left + right, top + bottom)
return size

def doLayout(self, rect, testonly):
left, top, right, bottom = self.getContentsMargins()
effective = rect.adjusted(+left, +top, -right, -bottom)
x = effective.x()
y = effective.y()
lineheight = 0
for item in self._items:
widget = item.widget()
hspace = self.horizontalSpacing()
if hspace == -1:
hspace = widget.style().layoutSpacing(
QtWidgets.QSizePolicy.PushButton,
QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Horizontal)
vspace = self.verticalSpacing()
if vspace == -1:
vspace = widget.style().layoutSpacing(
QtWidgets.QSizePolicy.PushButton,
QtWidgets.QSizePolicy.PushButton, QtCore.Qt.Vertical)
nextX = x + item.sizeHint().width() + hspace
if nextX - hspace > effective.right() and lineheight > 0:
x = effective.x()
y = y + lineheight + vspace
nextX = x + item.sizeHint().width() + hspace
lineheight = 0
if not testonly:
item.setGeometry(
QtCore.QRect(QtCore.QPoint(x, y), item.sizeHint()))
x = nextX
lineheight = max(lineheight, item.sizeHint().height())
return y + lineheight - rect.y() + bottom

def smartSpacing(self, pm):
parent = self.parent()
if parent is None:
return -1
elif parent.isWidgetType():
return parent.style().pixelMetric(pm, None, parent)
else:
return parent.spacing()

class Bubble(QtWidgets.QLabel):
def __init__(self, text):
super(Bubble, self).__init__(text)
self.word = text
self.setContentsMargins(5, 5, 5, 5)

def paintEvent(self, event):
painter = QtGui.QPainter(self)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
painter.drawRoundedRect(
0, 0, self.width() - 1, self.height() - 1, 5, 5)
super(Bubble, self).paintEvent(event)

class MainWindow(QtWidgets.QMainWindow):
def __init__(self, text, parent=None):
super(MainWindow, self).__init__(parent)
self.mainArea = QtWidgets.QScrollArea(self)
self.mainArea.setWidgetResizable(True)
widget = QtWidgets.QWidget(self.mainArea)
widget.setMinimumWidth(50)
layout = FlowLayout(widget)
self.words = []
for word in text.split():
label = Bubble(word)
label.setFont(QtGui.QFont('SblHebrew', 18))
label.setFixedWidth(label.sizeHint().width())
self.words.append(label)
layout.addWidget(label)
self.mainArea.setWidget(widget)
self.setCentralWidget(self.mainArea)

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)
window = MainWindow('Harry Potter is a series of fantasy literature')
window.show()
sys.exit(app.exec_())

关于python - PyQt:QScrollArea 内小部件的环绕式布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58473405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com