因此,我为某些任务添加了一个加载栏,但它会持续无限长时间,而无需使用它,我可以在 10 秒内获得结果。
这是我现在正在使用的加载栏类
class LoadingDialog(QDialog):
def __init__(self):
super().__init__()
self.setWindowTitle("Working on your task")
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
self.setFixedSize(300, 100) # Fixed size dialog
self.progress = QProgressBar(self)
self.progress.setGeometry(30, 40, 240, 30)
self.progress.setRange(0, 0) # Indeterminate progress bar
self.label = QLabel("Enumerating Please Wait...", self)
self.label.setGeometry(110, 10, 80, 20)
self.setLayout(QVBoxLayout())
self.layout().addWidget(self.label)
self.layout().addWidget(self.progress)
def showEvent(self, event):
super().showEvent(event)
self.progress.setRange(0, 0) # Start indeterminate progress
def closeEvent(self, event):
super().closeEvent(event)
self.progress.setRange(0, 0) # Reset progress on close
我在需要它的主要 GUI 功能中像这样使用它
self.loading_dialog.exec()
self.output_text.clear()
self.output_text.append(f"Enumerating subdomains for {domain} using wordlist...\n")
subdomains = self.subdomain_enum(domain, wordlist)
if subdomains:
self.display_subdomains("Wordlist", subdomains)
else:
self.output_text.append("No subdomains found.")
self.loading_dialog.close()
这是需要 10 到 20 秒的功能,因为我提供的单词列表只有 10 或 12 个单词。
def subdomain_enum(self, domain, wordlist):
output = []
subdomains = []
with open(wordlist, 'r') as file:
subdomains = file.read().splitlines()
for subdomain in subdomains:
try:
full_domain = f"{subdomain}.{domain}"
result = dns.resolver.resolve(full_domain, 'A')
for ipval in result:
output_line = f'{full_domain} | {ipval.to_text()}'
output.append(output_line)
except Exception as e:
pass
return output
这是用于显示输出框是文本浏览器的结果
def display_subdomains(self, source, subdomains):
self.output_text.append(f"From {source}:")
if subdomains:
for subdomain in subdomains:
self.output_text.append(f" - {subdomain}")
else:
self.output_text.append(f" No subdomains found from {source}.")
现在我还没有尝试很多解决方案,因为我在网上没有看到与此相关的解决方案,因此需要帮助。谢谢你。
QDialog.exec()
的文档(强调我的):
将对话框显示为模式对话框,阻塞直到用户关闭它。
这意味着在对话框关闭之前,该行之后的任何内容都不会被执行。
open()
函数:
将对话框显示为窗口模式对话框,立即返回。
现在,即使使用
open()
将允许程序继续执行以下指令,问题是之后发生的事情可能会发生 阻塞,这意味着事件循环将无法执行任何操作,包括正确执行同时更新用户界面。
您可能最终会得到一个看起来冻结的空窗口,并且一旦其他函数返回,该窗口就会关闭。
在像这样的简单情况下,代码的阻塞部分中发生的事情基于相对“快速”的处理循环(每次迭代可能需要不到一秒),强制事件循环处理其通过调用
QApplication.processEvents()
: 进行事件
def subdomain_enum(self, domain, wordlist):
output = []
subdomains = []
with open(wordlist, 'r') as file:
subdomains = file.read().splitlines()
for subdomain in subdomains:
QApplication.processEvents()
... # the rest of the code
但请注意,这只是基于有根据的猜测和希望一切正常:
dns.resolver.resolve()
可能需要更多时间(可能是由于网络问题),结果可能仍然冻结用户界面直到收到回复或最终出现错误。
处理 I/O(包括网络访问)时,通常且强烈建议将逻辑移至单独的线程中。
请注意,UI 元素不是线程安全的,因此您必须不要尝试从另一个线程访问它们。唯一正确的方法是使用信号,可能是将“worker”逻辑移至 QThread。
我建议您对此事进行一些研究,并最终发布一个带有相关[mre]的问题,以防您无法使其按预期工作。