I have a problem when trying to group, radioButton generated in a loop, together so that each line has its one buttonGroup and can be checked separetly.
Here is a stripped version of my code:
def ui_layout(self):
self.main_layout = QVBoxLayout()
self.setLayout(self.main_layout)
attrs = ['a', 'b']
for attr in attrs:
buttonGroup = QButtonGroup()
self.attr_layout = QHBoxLayout()
self.main_layout.addLayout(self.attr_layout)
self.rb1 = QRadioButton('{}_rb1'.format(attr))
self.attr_layout.addWidget(self.rb1)
buttonGroup.addButton(self.rb1)
self.rb2 = QRadioButton('{}_rb2'.format(attr))
self.attr_layout.addWidget(self.rb2)
buttonGroup.addButton(self.rb2)
All I get is this :
Here's the full code if you wanna try stuff : https://pastebin.com/3vJ4DXER
Try it:
import sys
from PyQt5.QtWidgets import (QRadioButton, QVBoxLayout, QHBoxLayout,
QButtonGroup, QApplication, QWidget)
class Window(QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.main_layout = QVBoxLayout()
self.setLayout(self.main_layout)
attrs = ['a', 'b']
self.buttonGroup = ['a', 'b']
for i, attr in enumerate(attrs):
self.buttonGroup[i] = QButtonGroup()
self.attr_layout = QHBoxLayout()
self.main_layout.addLayout(self.attr_layout)
self.rb1 = QRadioButton('{}_rb1'.format(attr))
self.attr_layout.addWidget(self.rb1)
self.buttonGroup[i].addButton(self.rb1)
self.rb2 = QRadioButton('{}_rb2'.format(attr))
self.attr_layout.addWidget(self.rb2)
self.buttonGroup[i].addButton(self.rb2)
self.buttonGroup[i].buttonClicked.connect(self.check_button)
def check_button(self, radioButton):
print("radioButton-> `{}`".format(radioButton.text()))
app = QApplication(sys.argv)
a_window = Window()
a_window.show()
sys.exit(app.exec_())
Related
I want to be able to move a layout to another layout based on a user input. I have the following code which does not appear to work for me. If I switch lines 31 and 34 so that they operate on the widget rather than the layout then I get the expected behaviour but I am hoping to operate on all widgets within a layout by just moving the layout.
import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QHBoxLayout, QLabel, QApplication, QVBoxLayout
class b(QWidget):
def __init__(self, name):
super(b, self).__init__()
self.layout = QVBoxLayout(self)
lbl_1 = QLabel(name)
self.layout.addWidget(lbl_1)
class a(QWidget):
def __init__(self):
super(a, self).__init__()
self.layout = QHBoxLayout(self)
self.widget_1 = b('widget 1')
self.widget_2 = b('widget 2')
self.layout.addWidget(self.widget_1)
self.layout.addWidget(self.widget_2)
self.button_layout = QHBoxLayout()
self.move_layout = QPushButton('Move to other layout')
self.move_layout.clicked.connect(lambda: self.move_button())
self.button_layout.addWidget(self.move_layout)
self.widget = 'widget_2'
self.widget_2.layout.addLayout(self.button_layout)
def move_button(self):
if self.widget == 'widget_2':
self.widget_1.layout.addLayout(self.button_layout)
self.widget = 'widget_1'
else:
self.widget_2.layout.addLayout(self.button_layout)
self.widget = 'widget_2'
print('moved widget to {}'.format(self.widget))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = a()
window.show()
sys.exit(app.exec_())
Edit: to clarify, In the example above, the layout I want to move (self.button_layout) is a child layout of self.widget_2.layout. When I click the pushbutton, I want the self.button_layout to be set as a child layout of self.widget_1.layout. Essentially it will do what the code below does but using addLayout instead of addWidget.
import sys
from PyQt5.QtWidgets import QPushButton, QWidget, QHBoxLayout, QLabel, QApplication, QVBoxLayout
class b(QWidget):
def __init__(self, name):
super(b, self).__init__()
self.layout = QVBoxLayout(self)
lbl_1 = QLabel(name)
self.layout.addWidget(lbl_1)
class a(QWidget):
def __init__(self):
super(a, self).__init__()
self.layout = QHBoxLayout(self)
self.widget_1 = b('widget 1')
self.widget_2 = b('widget 2')
self.layout.addWidget(self.widget_1)
self.layout.addWidget(self.widget_2)
self.button_layout = QHBoxLayout()
self.move_layout = QPushButton('Move to other layout')
self.move_layout.clicked.connect(lambda: self.move_button())
self.button_layout.addWidget(self.move_layout)
self.widget = 'widget_2'
self.widget_2.layout.addLayout(self.button_layout)
def move_button(self):
if self.widget == 'widget_2':
self.widget_1.layout.addWidget(self.move_layout)
self.widget = 'widget_1'
else:
self.widget_2.layout.addWidget(self.move_layout)
self.widget = 'widget_2'
print('moved widget to {}'.format(self.widget))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = a()
window.show()
sys.exit(app.exec_())
The problem is that if a layout has a parent then it cannot be changed as the error message indicates:
QLayout::addChildLayout: layout "" already has a parent
One possible solution is to remove the parent:
def move_button(self):
self.button_layout.setParent(None)
if self.widget == "widget_2":
self.widget_1.layout.addLayout(self.button_layout)
self.widget = "widget_1"
else:
self.widget_2.layout.addLayout(self.button_layout)
self.widget = "widget_2"
print("moved widget to {}".format(self.widget))
Another alternative is to place the layout in a QWidget that is the container and that place it in the required layout:
class a(QWidget):
def __init__(self):
super(a, self).__init__()
layout = QHBoxLayout(self)
self.widget_1 = b("widget 1")
self.widget_2 = b("widget 2")
layout.addWidget(self.widget_1)
layout.addWidget(self.widget_2)
self.container = QWidget()
container_layout = QHBoxLayout(self.container)
button = QPushButton("Move to other layout")
button.clicked.connect(self.move_button)
container_layout.addWidget(button)
self.widget = "widget_1"
self.move_button()
def move_button(self):
if self.widget == "widget_2":
self.widget_1.layout.addWidget(self.container)
self.widget = "widget_1"
else:
self.widget_2.layout.addWidget(self.container)
self.widget = "widget_2"
print("moved widget to {}".format(self.widget))
This question already has answers here:
How do I assert the identity of a PyQt5 signal?
(2 answers)
Closed 2 years ago.
I've created a search engine in PyQt5, using the code below:
import sys
from PyQt5.QtWidgets import (
QWidget, QLineEdit, QLabel, QScrollArea, QMainWindow,
QApplication, QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy, QCompleter, QPushButton
)
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
tlist = ['thing1', 'thing2', 'thing3', 'thing4']
class Label(QWidget):
def __init__(self, name):
super(Label, self).__init__()
self.name = name
self.lbl = QLabel(self.name)
self.lbl.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
self.btn = QPushButton("Preview")
self.btn.setMaximumSize(QtCore.QSize(100,100))
self.btn.clicked.connect(self.printsignal)
self.hbox = QHBoxLayout()
self.hbox.addWidget(self.lbl)
self.hbox.addWidget(self.btn)
self.setLayout(self.hbox)
def show(self):
for labels in [self, self.lbl]:
labels.setVisible(True)
def hide(self):
for labels in [self, self.lbl]:
labels.setVisible(False)
def printsignal(self):
print("clicked")
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__()
self.controls = QWidget()
self.controlsLayout = QVBoxLayout()
self.widgets = []
for name in tlist:
item = Label(name)
self.controlsLayout.addWidget(item)
self.widgets.append(item)
spacer = QSpacerItem(1, 1, QSizePolicy.Minimum, QSizePolicy.Expanding)
self.controlsLayout.addItem(spacer)
self.controls.setLayout(self.controlsLayout)
self.scroll = QScrollArea()
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.controls)
self.searchbar = QLineEdit()
self.searchbar.textChanged.connect(self.update_display)
self.completer = QCompleter(tlist)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.searchbar.setCompleter(self.completer)
container = QWidget()
containerLayout = QVBoxLayout()
containerLayout.addWidget(self.searchbar)
containerLayout.addWidget(self.scroll)
container.setLayout(containerLayout)
self.setCentralWidget(container)
self.setGeometry(600, 100, 800, 600)
self.setWindowTitle('Search Engine')
def update_display(self, text):
for widget in self.widgets:
if text.lower() in widget.name.lower():
widget.show()
else:
widget.hide()
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
The problem I have is, all the buttons share the same function and I don't know how to make them have different signals, as they are generated automatically. Basically, if I run the code it will show up like
this:
and when I press any of the buttons, it will print "clicked" (as in printsignal function). What I want is a different function for each button. Is there a way to do that?
Normally you can use self.sender().text() to get text from QButton which generated signal.
But because you create own widget Label with QButton and QLabel and you want text from label so you can get directly self.name
def printsignal(self):
print("clicked", self.name)
eventually self.lbl.text()
def printsignal(self):
print("clicked", self.lbl.text())
Working code.
I removed show(), hide() because you don't need it
import sys
from PyQt5.QtWidgets import (
QWidget, QLineEdit, QLabel, QScrollArea, QMainWindow,
QApplication, QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy, QCompleter, QPushButton
)
from PyQt5 import QtCore
from PyQt5.QtCore import Qt
tlist = ['thing1', 'thing2', 'thing3', 'thing4']
class Label(QWidget):
def __init__(self, name):
super().__init__()
self.name = name
self.lbl = QLabel(self.name)
self.lbl.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
self.btn = QPushButton("Preview")
self.btn.setMaximumSize(QtCore.QSize(100,100))
self.btn.clicked.connect(self.printsignal)
self.hbox = QHBoxLayout()
self.hbox.addWidget(self.lbl)
self.hbox.addWidget(self.btn)
self.setLayout(self.hbox)
def printsignal(self):
print("clicked", self.name)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super().__init__()
self.controls = QWidget()
self.controlsLayout = QVBoxLayout()
self.widgets = []
for name in tlist:
item = Label(name)
self.controlsLayout.addWidget(item)
self.widgets.append(item)
spacer = QSpacerItem(1, 1, QSizePolicy.Minimum, QSizePolicy.Expanding)
self.controlsLayout.addItem(spacer)
self.controls.setLayout(self.controlsLayout)
self.scroll = QScrollArea()
self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scroll.setWidgetResizable(True)
self.scroll.setWidget(self.controls)
self.searchbar = QLineEdit()
self.searchbar.textChanged.connect(self.update_display)
self.completer = QCompleter(tlist)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.searchbar.setCompleter(self.completer)
container = QWidget()
containerLayout = QVBoxLayout()
containerLayout.addWidget(self.searchbar)
containerLayout.addWidget(self.scroll)
container.setLayout(containerLayout)
self.setCentralWidget(container)
self.setGeometry(600, 100, 800, 600)
self.setWindowTitle('Search Engine')
def update_display(self, text):
for widget in self.widgets:
if text.lower() in widget.name.lower():
widget.show()
else:
widget.hide()
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Is it possible to enable/disable a QTreeWidget from updating?
I want to add rows to my tree and update it manually with a button. Obviously when i add a row to the TreeWidget it will be shown in the table. Is there a way to disable this so i can add like 100 rows and than update it once? If not is there a solution with a TreeView?
import sys
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction, QTreeWidget, QTreeWidgetItem
class Table(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.resize(800, 600)
self.setMinimumSize(QSize(800, 600))
self.table = QTreeWidget()
self.table.setHeaderLabels(["Description", "Price"])
self.setCentralWidget(self.table)
self.car = QTreeWidgetItem(["Car"])
self.house = QTreeWidgetItem(["House"])
self.table.addTopLevelItem(self.car)
self.table.addTopLevelItem(self.house)
toolbar = QToolBar("Toolbar")
carAction = QAction("Car", self)
carAction.triggered.connect(self.addToCar)
houseAction = QAction("House", self)
houseAction.triggered.connect(self.addToHouse)
updateAction = QAction("Update", self)
updateAction.triggered.connect(self.update)
toolbar.addAction(carAction)
toolbar.addAction(houseAction)
toolbar.addAction(updateAction)
self.addToolBar(toolbar)
def addToCar(self):
child = QTreeWidgetItem(["Audi", str(25000)])
self.car.addChild(child)
def addToHouse(self):
child = QTreeWidgetItem(["Villa", str(500000)])
self.house.addChild(child)
def update(self):
pass
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit( app.exec_() )
I do not know of a way to "suspend" tree updates, but what about using lists to store the children until one decides to update? See the modified example below (modifications are commented):
import sys
from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction, QTreeWidget, QTreeWidgetItem
class Table(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.resize(800, 600)
self.setMinimumSize(QSize(800, 600))
self.table = QTreeWidget()
self.table.setHeaderLabels(["Description", "Price"])
self.setCentralWidget(self.table)
self.car = QTreeWidgetItem(["Car"])
self.house = QTreeWidgetItem(["House"])
self.table.addTopLevelItem(self.car)
self.table.addTopLevelItem(self.house)
# initialize empty lists which will keep track of generated children
self.car_list, self.house_list = [], []
toolbar = QToolBar("Toolbar")
carAction = QAction("Car", self)
carAction.triggered.connect(self.addToCar)
houseAction = QAction("House", self)
houseAction.triggered.connect(self.addToHouse)
updateAction = QAction("Update", self)
updateAction.triggered.connect(self.update)
toolbar.addAction(carAction)
toolbar.addAction(houseAction)
toolbar.addAction(updateAction)
self.addToolBar(toolbar)
def addToCar(self):
child = QTreeWidgetItem(["Audi", str(25000)])
# instead of adding them directly to the tree, keep them in the list
self.car_list.append(child)
def addToHouse(self):
child = QTreeWidgetItem(["Villa", str(500000)])
# instead of adding them directly to the tree, keep them in the list
self.house.addChild(child)
def update(self):
# update the tree and reset the lists
self.car.addChildren(self.car_list)
self.house.addChildren(self.house_list)
self.car_list, self.house_list = [], []
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Table()
win.show()
sys.exit( app.exec_() )
I want to get a state from QCheckBox inside QTableWidget cell.
I've made example code for this issue.
import sys
from PyQt5.QtCore import Qt, QSettings
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtWidgets import QPushButton, QTableWidget, QCheckBox, QTextEdit
class TestUI(QWidget):
def __init__(self):
super().__init__()
self.btn = QPushButton("Get Data")
self.tbl = QTableWidget()
self.log = QTextEdit()
self.init_ui()
def init_ui(self):
self.btn.clicked.connect(self.get_data)
self.tbl.setFocusPolicy(Qt.NoFocus)
self.tbl.setMinimumHeight(255)
self.tbl.setMaximumHeight(255)
self.tbl.setRowCount(20)
self.tbl.setColumnCount(3)
self.tbl.horizontalHeader().setStretchLastSection(True)
self.tbl.setHorizontalHeaderLabels(["", "Option", "Value"])
self.tbl.resizeRowsToContents()
self.tbl.resizeColumnsToContents()
for row in range(20):
chk_box = QCheckBox()
chk_box.setCheckState(Qt.Unchecked)
cell = QWidget()
hlayout = QHBoxLayout()
hlayout.addWidget(chk_box)
hlayout.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
hlayout.setContentsMargins(0, 0, 0, 0)
cell.setLayout(hlayout)
self.tbl.setCellWidget(row, 0, cell)
vlayout = QVBoxLayout()
vlayout.addWidget(self.btn)
vlayout.addWidget(self.tbl)
vlayout.addWidget(self.log)
self.setLayout(vlayout)
self.show()
def get_data(self):
self.log.clear()
self.log.append(self.tbl.cellWidget(0, 0).isChecked())
self.log.append(self.tbl.cellWidget(0, 1).text())
self.log.append(self.tbl.cellWidget(0, 2).text())
if __name__ == "__main__":
APP = QApplication(sys.argv)
ex = TestUI()
sys.exit(APP.exec_())
How can I do this? I can't get the state through this code.
I think the code should be self.log.append(self.tbl.cellWidget(0, 0).????.isChecked()).
But I do not know exactly how to do it.
Please help me.
If the code that places the widget in column 0 is analyzed:
chk_box = QCheckBox()
chk_box.setCheckState(Qt.Unchecked)
cell = QWidget()
hlayout = QHBoxLayout()
hlayout.addWidget(chk_box)
hlayout.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
hlayout.setContentsMargins(0, 0, 0, 0)
cell.setLayout(hlayout)
self.tbl.setCellWidget(row, 0, cell)
It is noted that the widget set is not the QCheckBox but a QWidget, and the QCheckBox is the son of the QWidget so that information can be used to obtain it using the findChild() method. On the other hand, the item method may return None, so you should check if it is not, since it could throw an exception:
def get_data(self):
self.log.clear()
widget = self.tbl.cellWidget(0, 0)
if widget is not None:
chk_box = widget.findChild(QCheckBox)
if chk_box is not None:
self.log.append(str(chk_box.isChecked()))
it1 = self.tbl.item(0, 1)
self.log.append(it1.text() if it1 is not None else "")
it2 = self.tbl.item(0, 2)
self.log.append(it2.text() if it2 is not None else "")
A more elegant version of the above is to make the "cell" a custom widget that exposes the isChecked() method of the QCheckBox:
class Widget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.chk_box = QCheckBox()
self.chk_box.setCheckState(Qt.Unchecked)
hlayout = QHBoxLayout(self)
hlayout.addWidget(self.chk_box)
hlayout.setAlignment(Qt.AlignCenter)
hlayout.setContentsMargins(0, 0, 0, 0)
def isChecked(self):
return self.chk_box.isChecked()
class TestUI(QWidget):
def __init__(self):
super().__init__()
self.btn = QPushButton("Get Data")
self.tbl = QTableWidget()
self.log = QTextEdit()
self.init_ui()
def init_ui(self):
self.btn.clicked.connect(self.get_data)
self.tbl.setFocusPolicy(Qt.NoFocus)
self.tbl.setMinimumHeight(255)
self.tbl.setMaximumHeight(255)
self.tbl.setRowCount(20)
self.tbl.setColumnCount(3)
self.tbl.horizontalHeader().setStretchLastSection(True)
self.tbl.setHorizontalHeaderLabels(["", "Option", "Value"])
self.tbl.resizeRowsToContents()
self.tbl.resizeColumnsToContents()
for row in range(20):
cell = Widget()
self.tbl.setCellWidget(row, 0, cell)
vlayout = QVBoxLayout(self)
vlayout.addWidget(self.btn)
vlayout.addWidget(self.tbl)
vlayout.addWidget(self.log)
self.show()
def get_data(self):
self.log.clear()
widget = self.tbl.cellWidget(0, 0)
if widget is not None:
self.log.append(str(widget.isChecked()))
it1 = self.tbl.item(0, 1)
self.log.append(it1.text() if it1 is not None else "")
it2 = self.tbl.item(0, 2)
self.log.append(it2.text() if it2 is not None else "")
It can be deduced that you use the QWidget to center the QCheckBox inside the cell but I think it can be optimized to avoid creating widgets using a QProxyStyle, and then access the information through the checkState() method of the QTableWidgetItem:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
QApplication,
QWidget,
QHBoxLayout,
QVBoxLayout,
QPushButton,
QTableWidget,
QTextEdit,
QTableWidgetItem,
QProxyStyle,
QStyle,
)
class ProxyStyle(QProxyStyle):
def subElementRect(self, element, option, widget):
r = super().subElementRect(element, option, widget)
if element == QStyle.SE_ItemViewItemCheckIndicator:
r.moveCenter(option.rect.center())
return r
class TestUI(QWidget):
def __init__(self):
super().__init__()
self.btn = QPushButton("Get Data")
self.tbl = QTableWidget()
self.log = QTextEdit()
self.init_ui()
def init_ui(self):
self.btn.clicked.connect(self.get_data)
proxy = ProxyStyle()
self.tbl.setStyle(proxy)
self.tbl.setFocusPolicy(Qt.NoFocus)
self.tbl.setFixedHeight(255)
self.tbl.setRowCount(20)
self.tbl.setColumnCount(3)
self.tbl.horizontalHeader().setStretchLastSection(True)
self.tbl.setHorizontalHeaderLabels(["", "Option", "Value"])
self.tbl.resizeRowsToContents()
self.tbl.resizeColumnsToContents()
for row in range(20):
it = QTableWidgetItem()
it.setCheckState(Qt.Checked)
self.tbl.setItem(row, 0, it)
vlayout = QVBoxLayout(self)
vlayout.addWidget(self.btn)
vlayout.addWidget(self.tbl)
vlayout.addWidget(self.log)
self.show()
def get_data(self):
self.log.clear()
it0 = self.tbl.item(0, 0)
self.log.append(str(it0.checkState() == Qt.Checked))
it1 = self.tbl.item(0, 1)
self.log.append(it1.text() if it1 is not None else "")
it2 = self.tbl.item(0, 2)
self.log.append(it2.text() if it2 is not None else "")
if __name__ == "__main__":
APP = QApplication(sys.argv)
ex = TestUI()
sys.exit(APP.exec_())
I try to make the QTextEdit change its width value to the length of the text that is entered in it.
But the problem is that when using the resize property it does not do anything and does not change the size
I am obeying the length of the current word in the list and that value is the one I try to send as a property width() to the QTextEdit
to get something like this:
from PyQt5.QtWidgets import QMainWindow,QWidget,QVBoxLayout,QApplication,QTextEdit,QPushButton,QScrollArea
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.lista = ["one","two","abcdefghijklmn","zxyw","xyxyxyxyx"]
self.widget = QWidget(self)
self.layout = QVBoxLayout(self.widget)
self.area = QScrollArea(self)
self.area.resize(400,300)
self.area.setWidget(self.widget)
self.area.setWidgetResizable(True)
self.plain =QTextEdit(self)
self.plain.move(0,305)
self.plain.resize(400,50)
self.boton = QPushButton(self)
self.boton.move(0,360)
self.boton.setText("Press")
self.boton.clicked.connect(self.Test)
def Test(self):
for i in self.lista:
longitud = len(i)*6.3
print(longitud)
self.text = QTextEdit(self)
self.text.document().setPlainText(i)
self.text.setReadOnly(True)
self.text.resize(longitud,10)
self.layout.addWidget(self.text)
app = QApplication([])
m = Main()
m.show()
m.resize(600,400)
app.exec()
Actually what I need is that the QTextEdit that are created to fill the QScrollArea conform to the size of the length of text characters
This is the result I get but what I need is that the QTextEdit have the width() to where the line ends
Here is my attempt to solve this problem using font metrics to measure the size of the text box contents:
import sys
from PyQt5.QtGui import QFontMetrics
from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QApplication, QTextEdit, QPushButton, QScrollArea
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.lista = ["one", "two", "abcdefghijklmn", "zxyw", "xyxyxyxyx"]
self.widget = QWidget(self)
self.layout = QVBoxLayout(self.widget)
self.area = QScrollArea(self)
self.area.resize(400,300)
self.area.setWidget(self.widget)
self.area.setWidgetResizable(True)
self.plain = QTextEdit(self)
self.plain.move(0,305)
self.plain.resize(400,50)
self.boton = QPushButton(self)
self.boton.move(0,360)
self.boton.setText("Press")
self.boton.clicked.connect(self.Test)
def Test(self):
for i in self.lista:
text = QTextEdit(self)
text.document().setPlainText(i)
font = text.document().defaultFont()
fontMetrics = QFontMetrics(font)
textSize = fontMetrics.size(0, text.toPlainText())
w = textSize.width() + 10
h = textSize.height() + 10
text.setMinimumSize(w, h)
text.setMaximumSize(w, h)
text.resize(w, h)
text.setReadOnly(True)
self.layout.addWidget(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
m = Main()
m.show()
m.resize(600, 400)
sys.exit(app.exec_())
Result: