0

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:
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?

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
LonelyDEV
  • 9
  • 1
  • 1) what should happen instead of printing the message? 2) the overrides of `show` and `hide` are useless, remove them, as QWidget already provides it. – musicamante Feb 10 '21 at 11:55
  • 1) Each button should print their name (e.i.: if i press the button next to thing1, it should print "clicked thing1", if i press the button next to thing2, it should print "clicked thing2" and so on). 2) i didn't know that but it works so thank you – LonelyDEV Feb 10 '21 at 12:02
  • 2
    Since you have access to `self.lbl` from within `Label.printsignal`, you could use something like `print(f"clicked {self.lbl.text()}")`. – Heike Feb 10 '21 at 12:18
  • similar problem was yesterday - in function you can use `self.sender().text()` to get `text` from `Button` which generated signal. But if you create own widget `Label` then you can get directly values in your widget `Label` and every widget will get own value. – furas Feb 10 '21 at 14:18

1 Answers1

1

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_())
furas
  • 134,197
  • 12
  • 106
  • 148