Insert widget inside an other widget
-
I need insert widget inside an other widget (see picture):
This implementation has graphic bugs (see picture, the right side of the widget).
There is a main element of QListWidget. A QVBoxLayout has been assigned to it. 3 elements are inserted into QVBoxLayout: QHBoxLayout, Spacer and another QHBoxLayout. In the upper QHBoxLayout on the left is a Spacer, and on the right is QLineEdit (see picture). The lower QHBoxLayout is about the same, but instead of the QLineEdit there is a button with a "+".
Source:
def _setupViewWidget(self, obj): self.list_layout = QtWidgets.QVBoxLayout(obj) self.upper_spacer = QtWidgets.QSpacerItem( 10, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.list_layout.addItem(self.upper_spacer) self.bottom_layout = QtWidgets.QHBoxLayout() self.list_layout.addLayout(self.bottom_layout) self.add_button = QtWidgets.QPushButton("+") self.horizont_spacer = QtWidgets.QSpacerItem( 10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.bottom_layout.addItem(self.horizont_spacer) self.bottom_layout.addWidget(self.add_button) self.top_layout = QtWidgets.QHBoxLayout() self.search_line = QtWidgets.QLineEdit('Поиск') self.horizont_spacer_2 = QtWidgets.QSpacerItem( 10, 10, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.top_layout.addItem(self.horizont_spacer_2) self.top_layout.addWidget(self.search_line) self.top_layout.setStretch(0, 2) self.top_layout.setStretch(1, 1) self.list_layout.insertLayout(0, self.top_layout)
Is it "correctly" implemented? And how to get rid of bugs?
-
Hi and welcome to devnet,
Why are you putting a layout on a QListWidget ?
-
It would be cleaner to put the line edit on top of the QListWidget and the add button under its bottom.
QListWidget is typically a widget used within a layout and not with a layout on it.
-
I that case you are likely better off by positioning them manually rather than in a widget. Use the resize event of your QTableWidget to position them correctly with regard to the size of it.
-
@SGaist well, i did it (i removed the layout), but this implementation also has graphic bugs.
class QList(QtWidgets.QListWidget): def __init__(self, *args, **args2): super(QList, self).__init__(*args, **args2) self.button = QtWidgets.QPushButton('Test', parent=self) def resizeEvent(self, event): self.button.move(100, 100)
-
Don't forget to call the base class implementation of the methods you overload.
-
@Denni-0 It seems that I did such an implementation. but if it’s not difficult for you, show your implementation.
I also found another way using qgraphicsview:
from PyQt5.QtWidgets import (qApp,QMainWindow, QApplication, QGraphicsScene,QGraphicsView, QListWidget, QLineEdit, QPushButton) from PyQt5.QtCore import Qt,QRectF class View(QMainWindow): def __init__(self): super().__init__() self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.setCentralWidget(self.view) lst = QListWidget() lst.addItems([str(i) for i in range(100,200)]) lst.setAlternatingRowColors(True) line = QLineEdit() btn = QPushButton('+') self.proxyList = self.scene.addWidget(lst) self.proxyLine = self.scene.addWidget(line) self.proxyBtn = self.scene.addWidget(btn) def resizeEvent(self,e): w,h = self.view.width(),self.view.height() self.view.setSceneRect(0,0,w,h) self.proxyList.setGeometry(QRectF(0,0,w,h)) self.proxyLine.setGeometry(QRectF(w - 210,10,200,20)) self.proxyBtn.setGeometry(QRectF(w - 50,h - 30,20,20)) def closeEvent(self,e): qApp.quit() if __name__ == '__main__': import sys app = QApplication([]) w = View() w.resize(800,600) w.show() sys.exit(app.exec_())
This implementation has a boundary line around the button:
-
@SangreSan I solved the problem with displaying the button through setstylesheet:
QPushButton#addButton { background-color: rgba(134, 134, 134, 0.3); border-style: outset; border-width: 2px; border-color: rgba(20, 20, 20, 0.3); color: white; } QPushButton::pressed#addButton { background-color: rgba(0, 0, 0, 0.3); border-style: outset; border-width: 2px; border-color: rgba(20, 20, 20, 0.3); color: white; }