PyQt5 使用布局向小部件子类添加额外的小部件?
PyQt5 adding additional widgets to a widget subclass using layouts?
我正在尝试子类化 QListWidget
并在其上方添加一个搜索框。我知道我可以通过子类化 QWidget
并为其提供包含 QListWidget
和 QLineEdit
的布局来创建它,但我宁愿它是 QListWidget
的直接子类所以它可以很容易地替换我代码中现有的 QListWidgets
并保留所有可能被父小部件调用的继承方法。
这是我的尝试,但我不确定如何将 QListWidget
与 QLineEdit
一起放入布局中,layout.addWidget(self)
不起作用。
import re
from PyQt5 import QtCore, QtGui, QtWidgets
class SearchableListWidget(QtWidgets.QListWidget):
def __init__(self, items, parent=None):
super().__init__(parent=parent)
self.initial_items = items
self.set_items(items)
self.search_box = QtWidgets.QLineEdit()
self.search_box.textChanged.connect(self.filter)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.search_box)
self.setLayout(layout)
def filter(self):
filtered_items = [item for item in self.initial_items
if re.search(self.search_box.text().lower(), item.lower())]
self.set_items(filtered_items)
def get_items(self):
return [str(self.item(i).text()) for i in range(self.count())]
def set_items(self, items):
self.clear()
for name in items:
self.addItem(name)
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
test = SearchableListWidget(['a', 'b', 'c'])
test.show()
sys.exit(app.exec_())
我得到的:
我想要的:
问题出在您的程序结构上:window 是 SearchableListWidget,它是一个 QListWidget,您通过布局在其中放置了 QLineEdit,但正确的做法是创建一个 class继承自 QWidget 之类的容器,并通过 QVBoxLayout 垂直放置 QLineEdit 和 QListWidget:
import re
from PyQt5 import QtCore, QtGui, QtWidgets
class SearchableWidget(QtWidgets.QWidget):
def __init__(self, items, parent=None):
super().__init__(parent)
self.search_box = QtWidgets.QLineEdit()
self.search_box.textChanged.connect(self.filter)
self.list_widget = QtWidgets.QListWidget()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.search_box)
layout.addWidget(self.list_widget)
self.initial_items = items
self.set_items(items)
def filter(self):
filtered_items = [
item
for item in self.initial_items
if re.search(self.search_box.text().lower(), item.lower())
]
self.set_items(filtered_items)
def get_items(self):
return [
str(self.list_widget.item(i).text())
for i in range(self.list_widget.count())
]
def set_items(self, items):
self.list_widget.clear()
for name in items:
self.list_widget.addItem(name)
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
test = SearchableWidget(["a", "b", "c"])
test.show()
sys.exit(app.exec_())
我正在尝试子类化 QListWidget
并在其上方添加一个搜索框。我知道我可以通过子类化 QWidget
并为其提供包含 QListWidget
和 QLineEdit
的布局来创建它,但我宁愿它是 QListWidget
的直接子类所以它可以很容易地替换我代码中现有的 QListWidgets
并保留所有可能被父小部件调用的继承方法。
这是我的尝试,但我不确定如何将 QListWidget
与 QLineEdit
一起放入布局中,layout.addWidget(self)
不起作用。
import re
from PyQt5 import QtCore, QtGui, QtWidgets
class SearchableListWidget(QtWidgets.QListWidget):
def __init__(self, items, parent=None):
super().__init__(parent=parent)
self.initial_items = items
self.set_items(items)
self.search_box = QtWidgets.QLineEdit()
self.search_box.textChanged.connect(self.filter)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.search_box)
self.setLayout(layout)
def filter(self):
filtered_items = [item for item in self.initial_items
if re.search(self.search_box.text().lower(), item.lower())]
self.set_items(filtered_items)
def get_items(self):
return [str(self.item(i).text()) for i in range(self.count())]
def set_items(self, items):
self.clear()
for name in items:
self.addItem(name)
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
test = SearchableListWidget(['a', 'b', 'c'])
test.show()
sys.exit(app.exec_())
我得到的:
我想要的:
问题出在您的程序结构上:window 是 SearchableListWidget,它是一个 QListWidget,您通过布局在其中放置了 QLineEdit,但正确的做法是创建一个 class继承自 QWidget 之类的容器,并通过 QVBoxLayout 垂直放置 QLineEdit 和 QListWidget:
import re
from PyQt5 import QtCore, QtGui, QtWidgets
class SearchableWidget(QtWidgets.QWidget):
def __init__(self, items, parent=None):
super().__init__(parent)
self.search_box = QtWidgets.QLineEdit()
self.search_box.textChanged.connect(self.filter)
self.list_widget = QtWidgets.QListWidget()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.search_box)
layout.addWidget(self.list_widget)
self.initial_items = items
self.set_items(items)
def filter(self):
filtered_items = [
item
for item in self.initial_items
if re.search(self.search_box.text().lower(), item.lower())
]
self.set_items(filtered_items)
def get_items(self):
return [
str(self.list_widget.item(i).text())
for i in range(self.list_widget.count())
]
def set_items(self, items):
self.list_widget.clear()
for name in items:
self.list_widget.addItem(name)
if __name__ == "__main__":
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
test = SearchableWidget(["a", "b", "c"])
test.show()
sys.exit(app.exec_())