Не выполняется lambda QAction
Собственно. Если тот же самый экшн добавлять не в функции, а в цикле создания виджета, например - всё работает. Но мне нужно добавить этот экшн именно на результат функции.
К слову, если добавлять экшн без лямбды, а просто какой нибудь triggered.connect(label.hide) - то работает как надо.
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from threading import Thread
import requests
from bs4 import BeautifulSoup as bs
class MyWin(QWidget):
def __init__(self):
super(QWidget, self).__init__()
self.vbox = QVBoxLayout()
self.vbox.addStretch(1)
data = ['https://ru.stackoverflow.com/',
'https://youtube.com',
'https://www.google.com/'
]
for i in data:
if i.startswith('http'):
digit_label = QLabel(f'digit_label {i}')
Thread(target=self.parse_func, args=(i, 'success', digit_label)).start()
self.vbox.addWidget(digit_label)
self.scrollarea = QScrollArea(self)
self.scrollarea.resize(self.width(), self.height())
self.area = QWidget()
self.area.setLayout(self.vbox)
self.scrollarea.setWidget(self.area)
def parse_func(self, url, string, label):
page = requests.get(url)
soup = bs(page.text, "html.parser")
news = soup.find("title")
news = str(news).replace('<title>', '')
news = news.replace('</title>', '').lower()
if news:
label.setContextMenuPolicy(Qt.ActionsContextMenu)
label.setText(news)
show_action = QAction('Действие', self)
show_action.triggered.connect(lambda c, url=url, label=label: self.foo(url, label))
label.addAction(show_action)
def foo(self, url, label):
print(url)
label.setText('success')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = MyWin()
w.show()
sys.exit(app.exec_())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QWidget, QAction, QLabel, QVBoxLayout, QScrollArea
from threading import Thread
import requests
from bs4 import BeautifulSoup as bs
class Label(QLabel): # +++
def __init__(self, text, parent=None):
super(Label, self).__init__(parent)
self.url = ''
self.news = ''
self.setText(text)
self.show_action = QAction('Действие', self)
self.show_action.triggered.connect(self.on_triggered)
self.addAction(self.show_action)
def params(self, url, news):
self.url = url
self.news = news
def on_triggered(self):
self.window().foo(self.url, self.news, self)
class MyWin(QWidget):
def __init__(self):
super(QWidget, self).__init__()
self.vbox = QVBoxLayout()
self.vbox.addStretch(1)
data = ['https://ru.stackoverflow.com/',
'https://youtube.com',
'https://www.google.com/'
]
for i in data:
if i.startswith('http'):
digit_label = Label(f'digit_label {i}') # - QLabel(f'digit_label {i}')
Thread(target=self.parse_func, args=(i, 'success', digit_label)).start()
self.vbox.addWidget(digit_label)
self.vbox.addStretch(1) # ++
self.scrollarea = QScrollArea(self)
self.scrollarea.resize(self.width(), self.height())
self.area = QWidget()
self.area.resize(self.width(), self.height()) # +++
self.area.setLayout(self.vbox)
self.scrollarea.setWidget(self.area)
def parse_func(self, url, string, label):
page = requests.get(url)
soup = bs(page.text, "html.parser")
news = soup.find("title")
news = str(news).replace('<title>', '')
news = news.replace('</title>', '').lower()
if news:
label.setContextMenuPolicy(Qt.ActionsContextMenu)
label.setText(news)
label.params(url, news) # +++
def foo(self, url, news, label):
label.setText(f'<b>success:</b> {news}, {url}')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = MyWin()
w.show()
sys.exit(app.exec_())
