Как добавить текст из потока в контрол?
class External(QThread):
countChanged = pyqtSignal(int)
textChanged = pyqtSignal(str)
def __init__(self, url):
super().__init__()
self.url = url
self.sql(url)
def sql(self,url):
lines = open(file, "r")
lines = lines.readlines()
lines.close()
for line in lines:
self.textChanged.emit("text")
Хочу из потока добавить текст в контрол, но появляется две проблемы
1) Форма зависает напрочь
2) Текст не добавляется
Однако если я вместо self.calc.start() сделаю self.calc.sql("url") то данные на форме появляются, но форма также подвисает
def onButtonClick(self):
self.calc = External(self.urlbox.toPlainText())
self.calc.countChanged.connect(self.onCountChanged)
self.calc.textChanged.connect(self.onTextChanged)
self.calc.start()
def onCountChanged(self, value):
self.progress.setValue(value)
def onTextChanged(self, value):
self.log.insertPlainText(value)
self.log.ensureCursorVisible()
ps Полный листинг
import sys
import time
import requests
from pprint import pprint
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin
import os
from pathlib import Path
import sys
import time
import os
import certifi
import pycurl
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QDialog,QProgressBar, QPushButton, QLineEdit, QTextEdit,QRadioButton)
TIME_LIMIT = 100
class External(QThread):
countChanged = pyqtSignal(int)
textChanged = pyqtSignal(str)
def __init__(self, url):
super().__init__()
self.url = url
def run(self): # +++
self.sql(url)
def sql(self,url):
dir1 = str(Path().resolve())
file = os.path.join(dir1,'sqlpayload.txt')
logilfe = os.path.join(dir1,'log.txt')
sqlDosya = open(file, "r")
sqlPayload = sqlDosya.readlines()
sqlDosya.close()
index = 0
if "=" in url:
deger = str(url).find('=')
for i in sqlPayload:
index+=1
self.countChanged.emit(index)
try:
i = i.split("\n")[0]
yazi = str(url[0:deger + 1]) + str(i)
sonuc = requests.get(yazi)
if int(sonuc.status_code)==200:
# self.log.append("[+]Sqli paylaod: ", str(i))
self.textChanged.emit("[+]Sqli paylaod: "+ str(i)+"\n")
print ("[+]Sqli paylaod: ", str(i))
self.textChanged.emit("[+]Sqli URL: ", yazi+"\n")
print ("[+]Sqli URL: ", yazi)
rapor=open(logilfe,"a")
raporIcerik="[+]Sqli paylaod: "+str(i)+"\n"
raporIcerik+="[+]Sqli URL: "+yazi+"\n"
rapor.write(raporIcerik)
rapor.close()
else:
self.textChanged.emit("[-]Sqli paylaod: "+ str(i)+"\n")
print ("[-]Sqli paylaod: ", str(i))
self.textChanged.emit("[-]Sqli URL: "+ yazi+"\n")
print ("[-]Sqli URL: ", yazi)
rapor=open(logilfe,"a")
raporIcerik="[-]Sqli paylaod: "+str(i)+"\n"
raporIcerik+="[-]Sqli URL: "+yazi+"\n"
rapor.write(raporIcerik)
rapor.close()
except:
pass
else:
self.textChanged.emit("[-]Sqli isn't available"+"\n")
print ("[-]Sqli isn't available")
rapor = open(logilfe, "a")
raporIcerik = "[-]Sqli isn't available\n"
rapor.write(raporIcerik)
rapor.close()
class Actions(QDialog):
"""
Simple dialog that consists of a Progress Bar and a Button.
Clicking on the button results in the start of a timer and
updates the progress bar.
"""
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Progress Bar')
self.urlbox = QTextEdit(self)
self.urlbox.setText("https://xss-game.appspot.com/level1/frame?query=asd")
self.urlbox.setGeometry(5, 0, 465, 25)
self.progress = QProgressBar(self)
self.progress.setGeometry(5, 30, 500, 25)
self.progress.setMaximum(100)
self.log = QTextEdit(self)
self.log.move(5, 60)
self.log.setGeometry(5, 60, 465, 200)
self.button = QPushButton('Start', self)
self.button.move(5, 270)
self.xssradio = QRadioButton("xss",self)
self.xssradio.setChecked(1)
self.xssradio.move(100, 273)
self.sqliradio = QRadioButton("sqli",self)
self.sqliradio.move(150, 273)
self.show()
self.button.clicked.connect(self.onButtonClick)
def onButtonClick(self):
self.calc = External(self.urlbox.toPlainText())
self.calc.countChanged.connect(self.onCountChanged)
self.calc.textChanged.connect(self.onTextChanged)
self.calc.sql(self.urlbox.toPlainText())
def onCountChanged(self, value):
self.progress.setValue(value)
def onTextChanged(self, value):
self.log.insertPlainText(value)
self.log.ensureCursorVisible()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
sys.exit(app.exec_())
Ответы (1 шт):
Попробуйте так:
...
class External(QThread):
countChanged = pyqtSignal(int)
textChanged = pyqtSignal(str)
def __init__(self, url):
super().__init__()
self.url = url
# self.sql(url)
def run(self): # +++
self.sql(self.url) # + self.url
def sql(self, url):
lines = open(file, "r")
lines = lines.readlines()
lines.close()
for line in lines:
self.textChanged.emit("text")
...
Update
Основная ваша ошибка в неправильном вызове/старте дополнительного потока, который запускается self.calc.start(), что приводит к автоматическому запуску метода def run(self):, который вызовет метод def sql(self, url): командой self.sql(self.url). Обратите внимание, передается параметр self.url, а не url.
Я также добавил некоторые микро паузы self.msleep(5) в 5 ms, чтобы CPU не залипало на 100%.
Подставьте свой 'sqlpayload.txt' и попробуйте:
import sys
import time
import requests
from pprint import pprint
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin
import os
from pathlib import Path
import sys
import time
import os
import certifi
#import pycurl
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QDialog,QProgressBar, QPushButton, QLineEdit, QTextEdit,QRadioButton)
TIME_LIMIT = 100
class External(QThread):
countChanged = pyqtSignal(int)
textChanged = pyqtSignal(str)
def __init__(self, url):
super().__init__()
self.url = url
def run(self):
# self.sql(url) # --- НЕТ
self.sql(self.url) # +++ self.url !!!
def sql(self, url):
dir1 = str(Path().resolve())
# file = os.path.join(dir1,'sqlpayload.txt') # ! 'sqlpayload.txt' установите свой .txt
file = os.path.join(dir1,'test.txt') # ! 'test.txt'
logilfe = os.path.join(dir1,'log.txt')
sqlDosya = open(file, "r")
sqlPayload = sqlDosya.readlines()
sqlDosya.close()
index = 0
if "=" in url:
deger = str(url).find('=')
for i in sqlPayload:
index += 1
self.countChanged.emit(index)
self.msleep(5) # +++
try:
i = i.split("\n")[0]
yazi = str(url[0:deger + 1]) + str(i)
sonuc = requests.get(yazi)
if int(sonuc.status_code)==200:
# self.log.append("[+]Sqli paylaod: ", str(i))
self.textChanged.emit("[+]Sqli paylaod: "+ str(i)+"\n")
# print ("[+]Sqli paylaod: ", str(i))
self.msleep(5)
self.textChanged.emit("[+]Sqli URL: ", yazi+"\n")
# print ("[+]Sqli URL: ", yazi)
self.msleep(5)
rapor=open(logilfe,"a")
raporIcerik="[+]Sqli paylaod: "+str(i)+"\n"
raporIcerik+="[+]Sqli URL: "+yazi+"\n"
rapor.write(raporIcerik)
rapor.close()
else:
self.textChanged.emit("[-]Sqli paylaod: "+ str(i)+"\n")
# print ("[-]Sqli paylaod: ", str(i))
self.msleep(5)
self.textChanged.emit("[-]Sqli URL: "+ yazi+"\n")
# print ("[-]Sqli URL: ", yazi)
self.msleep(5)
rapor=open(logilfe,"a")
raporIcerik="[-]Sqli paylaod: "+str(i)+"\n"
raporIcerik+="[-]Sqli URL: "+yazi+"\n"
rapor.write(raporIcerik)
rapor.close()
except:
pass
else:
self.textChanged.emit("[-]Sqli isn't available"+"\n")
# print ("[-]Sqli isn't available")
rapor = open(logilfe, "a")
raporIcerik = "[-]Sqli isn't available\n"
rapor.write(raporIcerik)
rapor.close()
class Actions(QDialog):
"""
Simple dialog that consists of a Progress Bar and a Button.
Clicking on the button results in the start of a timer and
updates the progress bar.
"""
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Progress Bar')
self.urlbox = QTextEdit(self)
self.urlbox.setText("https://xss-game.appspot.com/level1/frame?query=asd")
self.urlbox.setGeometry(5, 0, 465, 25)
self.progress = QProgressBar(self)
self.progress.setGeometry(5, 30, 500, 25)
self.progress.setMaximum(100)
self.log = QTextEdit(self)
self.log.move(5, 60)
self.log.setGeometry(5, 60, 465, 200)
self.button = QPushButton('Start', self)
self.button.move(5, 270)
self.xssradio = QRadioButton("xss",self)
self.xssradio.setChecked(1)
self.xssradio.move(100, 273)
self.sqliradio = QRadioButton("sqli",self)
self.sqliradio.move(150, 273)
self.show()
self.button.clicked.connect(self.onButtonClick)
def onButtonClick(self):
self.calc = External(self.urlbox.toPlainText())
self.calc.countChanged.connect(self.onCountChanged)
self.calc.textChanged.connect(self.onTextChanged)
# self.calc.sql(self.urlbox.toPlainText()) # --- НЕТ
self.calc.start() # +++ start() !!!
def onCountChanged(self, value):
self.progress.setValue(value)
def onTextChanged(self, value):
self.log.insertPlainText(value)
self.log.ensureCursorVisible()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Actions()
sys.exit(app.exec_())
