Опять же мои любимые нейронки выполнили половину работы Впринципе говно полное ну норм Пародия пародию Код from PySide6 import QtCore, QtWidgets, QtGui import re import os # Регулярки для валидации EMAIL_REGEX = re.compile(r"^[\w\.-]+@[\w\.-]+\.\w+$") USERNAME_REGEX = re.compile(r"^@\w{3,30}$") PHONE_REGEX = re.compile(r"^\+\d{7,15}$") DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data') if not os.path.exists(DATA_DIR): os.makedirs(DATA_DIR) DATA_FILES = { 'emails': os.path.join(DATA_DIR, 'emails.txt'), 'usernames': os.path.join(DATA_DIR, 'usernames.txt'), 'names': os.path.join(DATA_DIR, 'names.txt'), 'phones': os.path.join(DATA_DIR, 'phones.txt') } class DBManager: def __init__(self): self.data = { 'emails': [], 'usernames': [], 'names': [], 'phones': [] } self.data_sets = { 'emails': set(), 'usernames': set(), 'names': set(), 'phones': set() } self.load_all() def load_all(self): for section in self.data: self.load_file(section) def load_file(self, section): path = DATA_FILES[section] if os.path.exists(path): with open(path, 'r', encoding='utf-8') as f: lines = f.read().splitlines() clean_lines = [line.strip() for line in lines if line.strip()] self.data[section] = clean_lines self.data_sets[section] = set(clean_lines) else: self.data[section] = [] self.data_sets[section] = set() def save_file(self, section): path = DATA_FILES[section] with open(path, 'w', encoding='utf-8') as f: for entry in self.data[section]: f.write(entry + '\n') def add_entry(self, section, entry): if entry not in self.data_sets[section]: self.data[section].append(entry) self.data_sets[section].add(entry) self.save_file(section) return True return False def remove_entry(self, section, entry): if entry in self.data_sets[section]: self.data_sets[section].remove(entry) self.data[section].remove(entry) self.save_file(section) return True return False def search(self, section, query): if not query: return self.data[section] q = query.lower() return [x for x in self.data[section] if q in x.lower()] def total_count(self): return sum(len(v) for v in self.data.values()) class ImportWorker(QtCore.QObject): progress = QtCore.Signal(int) # Процент выполнения finished = QtCore.Signal(int) # Сколько добавлено def __init__(self, manager, section, filepath): super().__init__() self.manager = manager self.section = section self.filepath = filepath self._is_running = True def stop(self): self._is_running = False @QtCore.Slot() def run(self): count_added = 0 try: with open(self.filepath, 'r', encoding='utf-8') as f: lines = f.read().splitlines() except Exception as e: self.finished.emit(-1) return total_lines = len(lines) batch_size = 1000 # функция валидации def validate(entry): entry = entry.strip() if self.section == 'emails': email_part = entry.split(':', 1)[0] return bool(EMAIL_REGEX.match(email_part)) if self.section == 'usernames': return bool(USERNAME_REGEX.match(entry)) if self.section == 'phones': return bool(PHONE_REGEX.match(entry)) if self.section == 'names': return len(entry) > 1 return False for start in range(0, total_lines, batch_size): if not self._is_running: break batch = lines[start:start + batch_size] for line in batch: line = line.strip() if validate(line) and line not in self.manager.data_sets[self.section]: self.manager.data[self.section].append(line) self.manager.data_sets[self.section].add(line) count_added += 1 self.progress.emit(min(100, int((start + batch_size) / total_lines * 100))) self.manager.save_file(self.section) self.finished.emit(count_added) class HackerStyleDBApp(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("DB panel") self.resize(1000, 700) self.setMinimumSize(800, 600) qr = self.frameGeometry() cp = QtGui.QGuiApplication.primaryScreen().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) self.manager = DBManager() self.stack = QtWidgets.QStackedWidget() self.setCentralWidget(self.stack) self.setStyleSheet(self.get_stylesheet()) self.pages = {} self.import_thread = None self.import_worker = None self.init_main_menu() for section in ['emails', 'usernames', 'names', 'phones']: self.create_section_page(section) self.stack.setCurrentWidget(self.pages['main_menu']) def get_stylesheet(self): return """ QWidget { background-color: #0f0f0f; color: #39ff14; font-family: Consolas, monospace; font-size: 14px; } QLineEdit, QListWidget { background-color: #1b1b1b; border: 1px solid #39ff14; border-radius: 5px; padding: 5px; selection-background-color: #005500; color: #39ff14; } QPushButton { background-color: #39ff14; border: none; color: #000; font-weight: 700; padding: 8px 15px; border-radius: 5px; min-width: 120px; max-width: 180px; } QPushButton:hover { background-color: #32cc12; } QPushButton:pressed { background-color: #1f6e07; } QLabel { color: #39ff14; } QListWidget::item:selected { background-color: #005500; color: #b3ff99; } QScrollBar:vertical { background: #0f0f0f; width: 12px; margin: 0px 0px 0px 0px; } QScrollBar::handle:vertical { background: #39ff14; min-height: 20px; border-radius: 6px; } QScrollBar::handle:vertical:hover { background: #32cc12; } """ def init_main_menu(self): widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout(widget) layout.setContentsMargins(50, 50, 50, 50) layout.setSpacing(30) title = QtWidgets.QLabel("Database Manager") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet("font-size: 32px; font-weight: 900; color: #39ff14;") layout.addWidget(title) counts = self.get_all_counts() self.main_info_label = QtWidgets.QLabel( f"All base amount: {counts['total']}\n" f"Emails: {counts['emails']}\n" f"Usernames: {counts['usernames']}\n" f"Names: {counts['names']}\n" f"Phones: {counts['phones']}" ) self.main_info_label.setAlignment(QtCore.Qt.AlignCenter) self.main_info_label.setStyleSheet("font-size: 18px; font-weight: 600; margin-bottom: 40px;") layout.addWidget(self.main_info_label) btn_emails = QtWidgets.QPushButton("Emails") btn_usernames = QtWidgets.QPushButton("Usernames") btn_names = QtWidgets.QPushButton("Names") btn_phones = QtWidgets.QPushButton("Phones") btn_emails.clicked.connect(lambda: self.go_to_section('emails')) btn_usernames.clicked.connect(lambda: self.go_to_section('usernames')) btn_names.clicked.connect(lambda: self.go_to_section('names')) btn_phones.clicked.connect(lambda: self.go_to_section('phones')) for btn in [btn_emails, btn_usernames, btn_names, btn_phones]: btn.setMinimumHeight(50) btn.setStyleSheet("font-size: 20px; font-weight: 700;") layout.addWidget(btn) layout.addStretch() self.pages['main_menu'] = widget self.stack.addWidget(widget) def get_all_counts(self): return { 'emails': len(self.manager.data['emails']), 'usernames': len(self.manager.data['usernames']), 'names': len(self.manager.data['names']), 'phones': len(self.manager.data['phones']), 'total': self.manager.total_count() } def go_to_section(self, section): self.stack.setCurrentWidget(self.pages[section]) def go_to_main(self): self.update_stats() self.stack.setCurrentWidget(self.pages['main_menu']) def update_stats(self): counts = self.get_all_counts() self.main_info_label.setText( f"All base: {counts['total']}\n" f"Emails: {counts['emails']}\n" f"Usernames: {counts['usernames']}\n" f"Names: {counts['names']}\n" f"Phones: {counts['phones']}" ) def create_section_page(self, section): widget = QtWidgets.QWidget() vlayout = QtWidgets.QVBoxLayout(widget) vlayout.setContentsMargins(25, 25, 25, 25) vlayout.setSpacing(12) hlayout_top = QtWidgets.QHBoxLayout() back_btn = QtWidgets.QPushButton("Back") back_btn.setMaximumWidth(110) back_btn.clicked.connect(self.go_to_main) hlayout_top.addWidget(back_btn) title = QtWidgets.QLabel(f"{section.capitalize()}") title.setStyleSheet("font-size: 24px; font-weight: 700; color: #39ff14;") title.setAlignment(QtCore.Qt.AlignCenter) hlayout_top.addWidget(title, stretch=1) hlayout_top.addStretch() vlayout.addLayout(hlayout_top) search_line = QtWidgets.QLineEdit() search_line.setPlaceholderText(f"Search in {section}...") vlayout.addWidget(search_line) list_widget = QtWidgets.QListWidget() list_widget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) list_widget.addItems(self.manager.data[section]) vlayout.addWidget(list_widget) entry_line = QtWidgets.QLineEdit() entry_line.setPlaceholderText(f"Add new to {section}...") entry_line.setClearButtonEnabled(True) vlayout.addWidget(entry_line) btn_layout = QtWidgets.QHBoxLayout() add_btn = QtWidgets.QPushButton("Add") delete_btn = QtWidgets.QPushButton("Delete Selected") import_btn = QtWidgets.QPushButton("Import") btn_layout.addWidget(add_btn) btn_layout.addWidget(delete_btn) btn_layout.addWidget(import_btn) vlayout.addLayout(btn_layout) def validate(entry): entry = entry.strip() if section == 'emails': email_part = entry.split(':', 1)[0] return bool(EMAIL_REGEX.match(email_part)) if section == 'usernames': return bool(USERNAME_REGEX.match(entry)) if section == 'phones': return bool(PHONE_REGEX.match(entry)) if section == 'names': return len(entry) > 1 return False def add_entry(): entry = entry_line.text().strip() if not entry: return if not validate(entry): QtWidgets.QMessageBox.warning(self, "Error", f"Wrong format for {section}!") return if entry in self.manager.data_sets[section]: QtWidgets.QMessageBox.information(self, "Info", f"This line already exists in {section}.") return self.manager.add_entry(section, entry) list_widget.addItem(entry) entry_line.clear() self.update_stats() add_btn.clicked.connect(add_entry) def search_and_filter(): query = search_line.text().strip() results = self.manager.search(section, query) list_widget.clear() list_widget.addItems(results) search_line.textChanged.connect(search_and_filter) def delete_selected(): selected_items = list_widget.selectedItems() if not selected_items: QtWidgets.QMessageBox.information(self, "Deletion", "No items selected for deletion.") return ret = QtWidgets.QMessageBox.question(self, "Deletion", f"Delete selected {len(selected_items)} lines?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.Yes: for item in selected_items: text = item.text() if text in self.manager.data_sets[section]: self.manager.remove_entry(section, text) list_widget.takeItem(list_widget.row(item)) self.update_stats() delete_btn.clicked.connect(delete_selected) def import_file(): path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select file to import", "", "Текстовые файлы (*.txt)") if path: # Запуск импортера в отдельном потоке self.import_worker = ImportWorker(self.manager, section, path) self.import_thread = QtCore.QThread() self.import_worker.moveToThread(self.import_thread) self.import_worker.progress.connect(self.on_import_progress) self.import_worker.finished.connect(self.on_import_finished) self.import_thread.started.connect(self.import_worker.run) self.import_worker.finished.connect(self.import_thread.quit) self.import_worker.finished.connect(self.import_worker.deleteLater) self.import_thread.finished.connect(self.import_thread.deleteLater) # Сохраним текущий виджет и list_widget для обновления позже self.current_list_widget = list_widget # Блокируем интерфейс кнопок на время импорта add_btn.setEnabled(False) delete_btn.setEnabled(False) import_btn.setEnabled(False) entry_line.setEnabled(False) search_line.setEnabled(False) self.import_thread.start() import_btn.clicked.connect(import_file) self.pages[section] = widget self.stack.addWidget(widget) def on_import_progress(self, percent): self.statusBar().showMessage(f"Importing... {percent}%") def on_import_finished(self, count_added): self.statusBar().clearMessage() # Разблокируем интерфейс for section in ['emails', 'usernames', 'names', 'phones']: if self.stack.currentWidget() == self.pages[section]: widget = self.pages[section] for w in widget.findChildren(QtWidgets.QPushButton): w.setEnabled(True) for w in widget.findChildren(QtWidgets.QLineEdit): w.setEnabled(True) if count_added == -1: QtWidgets.QMessageBox.warning(self, "Error", "Cannot read the file. Please check the file format.") return if count_added > 0: # Обновляем список self.current_list_widget.clear() self.current_list_widget.addItems(self.manager.data[self.stack.currentWidget().findChild(QtWidgets.QLabel).text().lower()]) self.update_stats() QtWidgets.QMessageBox.information(self, "Import", f"Succes, Lines imported: {count_added}") else: QtWidgets.QMessageBox.information(self, "Import", f"Could not add any new lines. All entries already exist in the database.") def main(): app = QtWidgets.QApplication([]) window = HackerStyleDBApp() window.show() app.exec() if __name__ == "__main__": main() Python from PySide6 import QtCore, QtWidgets, QtGui import re import os # Регулярки для валидации EMAIL_REGEX = re.compile(r"^[\w\.-]+@[\w\.-]+\.\w+$") USERNAME_REGEX = re.compile(r"^@\w{3,30}$") PHONE_REGEX = re.compile(r"^\+\d{7,15}$") DATA_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data') if not os.path.exists(DATA_DIR): os.makedirs(DATA_DIR) DATA_FILES = { 'emails': os.path.join(DATA_DIR, 'emails.txt'), 'usernames': os.path.join(DATA_DIR, 'usernames.txt'), 'names': os.path.join(DATA_DIR, 'names.txt'), 'phones': os.path.join(DATA_DIR, 'phones.txt') } class DBManager: def __init__(self): self.data = { 'emails': [], 'usernames': [], 'names': [], 'phones': [] } self.data_sets = { 'emails': set(), 'usernames': set(), 'names': set(), 'phones': set() } self.load_all() def load_all(self): for section in self.data: self.load_file(section) def load_file(self, section): path = DATA_FILES[section] if os.path.exists(path): with open(path, 'r', encoding='utf-8') as f: lines = f.read().splitlines() clean_lines = [line.strip() for line in lines if line.strip()] self.data[section] = clean_lines self.data_sets[section] = set(clean_lines) else: self.data[section] = [] self.data_sets[section] = set() def save_file(self, section): path = DATA_FILES[section] with open(path, 'w', encoding='utf-8') as f: for entry in self.data[section]: f.write(entry + '\n') def add_entry(self, section, entry): if entry not in self.data_sets[section]: self.data[section].append(entry) self.data_sets[section].add(entry) self.save_file(section) return True return False def remove_entry(self, section, entry): if entry in self.data_sets[section]: self.data_sets[section].remove(entry) self.data[section].remove(entry) self.save_file(section) return True return False def search(self, section, query): if not query: return self.data[section] q = query.lower() return [x for x in self.data[section] if q in x.lower()] def total_count(self): return sum(len(v) for v in self.data.values()) class ImportWorker(QtCore.QObject): progress = QtCore.Signal(int) # Процент выполнения finished = QtCore.Signal(int) # Сколько добавлено def __init__(self, manager, section, filepath): super().__init__() self.manager = manager self.section = section self.filepath = filepath self._is_running = True def stop(self): self._is_running = False @QtCore.Slot() def run(self): count_added = 0 try: with open(self.filepath, 'r', encoding='utf-8') as f: lines = f.read().splitlines() except Exception as e: self.finished.emit(-1) return total_lines = len(lines) batch_size = 1000 # функция валидации def validate(entry): entry = entry.strip() if self.section == 'emails': email_part = entry.split(':', 1)[0] return bool(EMAIL_REGEX.match(email_part)) if self.section == 'usernames': return bool(USERNAME_REGEX.match(entry)) if self.section == 'phones': return bool(PHONE_REGEX.match(entry)) if self.section == 'names': return len(entry) > 1 return False for start in range(0, total_lines, batch_size): if not self._is_running: break batch = lines[start:start + batch_size] for line in batch: line = line.strip() if validate(line) and line not in self.manager.data_sets[self.section]: self.manager.data[self.section].append(line) self.manager.data_sets[self.section].add(line) count_added += 1 self.progress.emit(min(100, int((start + batch_size) / total_lines * 100))) self.manager.save_file(self.section) self.finished.emit(count_added) class HackerStyleDBApp(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("DB panel") self.resize(1000, 700) self.setMinimumSize(800, 600) qr = self.frameGeometry() cp = QtGui.QGuiApplication.primaryScreen().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) self.manager = DBManager() self.stack = QtWidgets.QStackedWidget() self.setCentralWidget(self.stack) self.setStyleSheet(self.get_stylesheet()) self.pages = {} self.import_thread = None self.import_worker = None self.init_main_menu() for section in ['emails', 'usernames', 'names', 'phones']: self.create_section_page(section) self.stack.setCurrentWidget(self.pages['main_menu']) def get_stylesheet(self): return """ QWidget { background-color: #0f0f0f; color: #39ff14; font-family: Consolas, monospace; font-size: 14px; } QLineEdit, QListWidget { background-color: #1b1b1b; border: 1px solid #39ff14; border-radius: 5px; padding: 5px; selection-background-color: #005500; color: #39ff14; } QPushButton { background-color: #39ff14; border: none; color: #000; font-weight: 700; padding: 8px 15px; border-radius: 5px; min-width: 120px; max-width: 180px; } QPushButton:hover { background-color: #32cc12; } QPushButton:pressed { background-color: #1f6e07; } QLabel { color: #39ff14; } QListWidget::item:selected { background-color: #005500; color: #b3ff99; } QScrollBar:vertical { background: #0f0f0f; width: 12px; margin: 0px 0px 0px 0px; } QScrollBar::handle:vertical { background: #39ff14; min-height: 20px; border-radius: 6px; } QScrollBar::handle:vertical:hover { background: #32cc12; } """ def init_main_menu(self): widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout(widget) layout.setContentsMargins(50, 50, 50, 50) layout.setSpacing(30) title = QtWidgets.QLabel("Database Manager") title.setAlignment(QtCore.Qt.AlignCenter) title.setStyleSheet("font-size: 32px; font-weight: 900; color: #39ff14;") layout.addWidget(title) counts = self.get_all_counts() self.main_info_label = QtWidgets.QLabel( f"All base amount: {counts['total']}\n" f"Emails: {counts['emails']}\n" f"Usernames: {counts['usernames']}\n" f"Names: {counts['names']}\n" f"Phones: {counts['phones']}" ) self.main_info_label.setAlignment(QtCore.Qt.AlignCenter) self.main_info_label.setStyleSheet("font-size: 18px; font-weight: 600; margin-bottom: 40px;") layout.addWidget(self.main_info_label) btn_emails = QtWidgets.QPushButton("Emails") btn_usernames = QtWidgets.QPushButton("Usernames") btn_names = QtWidgets.QPushButton("Names") btn_phones = QtWidgets.QPushButton("Phones") btn_emails.clicked.connect(lambda: self.go_to_section('emails')) btn_usernames.clicked.connect(lambda: self.go_to_section('usernames')) btn_names.clicked.connect(lambda: self.go_to_section('names')) btn_phones.clicked.connect(lambda: self.go_to_section('phones')) for btn in [btn_emails, btn_usernames, btn_names, btn_phones]: btn.setMinimumHeight(50) btn.setStyleSheet("font-size: 20px; font-weight: 700;") layout.addWidget(btn) layout.addStretch() self.pages['main_menu'] = widget self.stack.addWidget(widget) def get_all_counts(self): return { 'emails': len(self.manager.data['emails']), 'usernames': len(self.manager.data['usernames']), 'names': len(self.manager.data['names']), 'phones': len(self.manager.data['phones']), 'total': self.manager.total_count() } def go_to_section(self, section): self.stack.setCurrentWidget(self.pages[section]) def go_to_main(self): self.update_stats() self.stack.setCurrentWidget(self.pages['main_menu']) def update_stats(self): counts = self.get_all_counts() self.main_info_label.setText( f"All base: {counts['total']}\n" f"Emails: {counts['emails']}\n" f"Usernames: {counts['usernames']}\n" f"Names: {counts['names']}\n" f"Phones: {counts['phones']}" ) def create_section_page(self, section): widget = QtWidgets.QWidget() vlayout = QtWidgets.QVBoxLayout(widget) vlayout.setContentsMargins(25, 25, 25, 25) vlayout.setSpacing(12) hlayout_top = QtWidgets.QHBoxLayout() back_btn = QtWidgets.QPushButton("Back") back_btn.setMaximumWidth(110) back_btn.clicked.connect(self.go_to_main) hlayout_top.addWidget(back_btn) title = QtWidgets.QLabel(f"{section.capitalize()}") title.setStyleSheet("font-size: 24px; font-weight: 700; color: #39ff14;") title.setAlignment(QtCore.Qt.AlignCenter) hlayout_top.addWidget(title, stretch=1) hlayout_top.addStretch() vlayout.addLayout(hlayout_top) search_line = QtWidgets.QLineEdit() search_line.setPlaceholderText(f"Search in {section}...") vlayout.addWidget(search_line) list_widget = QtWidgets.QListWidget() list_widget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) list_widget.addItems(self.manager.data[section]) vlayout.addWidget(list_widget) entry_line = QtWidgets.QLineEdit() entry_line.setPlaceholderText(f"Add new to {section}...") entry_line.setClearButtonEnabled(True) vlayout.addWidget(entry_line) btn_layout = QtWidgets.QHBoxLayout() add_btn = QtWidgets.QPushButton("Add") delete_btn = QtWidgets.QPushButton("Delete Selected") import_btn = QtWidgets.QPushButton("Import") btn_layout.addWidget(add_btn) btn_layout.addWidget(delete_btn) btn_layout.addWidget(import_btn) vlayout.addLayout(btn_layout) def validate(entry): entry = entry.strip() if section == 'emails': email_part = entry.split(':', 1)[0] return bool(EMAIL_REGEX.match(email_part)) if section == 'usernames': return bool(USERNAME_REGEX.match(entry)) if section == 'phones': return bool(PHONE_REGEX.match(entry)) if section == 'names': return len(entry) > 1 return False def add_entry(): entry = entry_line.text().strip() if not entry: return if not validate(entry): QtWidgets.QMessageBox.warning(self, "Error", f"Wrong format for {section}!") return if entry in self.manager.data_sets[section]: QtWidgets.QMessageBox.information(self, "Info", f"This line already exists in {section}.") return self.manager.add_entry(section, entry) list_widget.addItem(entry) entry_line.clear() self.update_stats() add_btn.clicked.connect(add_entry) def search_and_filter(): query = search_line.text().strip() results = self.manager.search(section, query) list_widget.clear() list_widget.addItems(results) search_line.textChanged.connect(search_and_filter) def delete_selected(): selected_items = list_widget.selectedItems() if not selected_items: QtWidgets.QMessageBox.information(self, "Deletion", "No items selected for deletion.") return ret = QtWidgets.QMessageBox.question(self, "Deletion", f"Delete selected {len(selected_items)} lines?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if ret == QtWidgets.QMessageBox.Yes: for item in selected_items: text = item.text() if text in self.manager.data_sets[section]: self.manager.remove_entry(section, text) list_widget.takeItem(list_widget.row(item)) self.update_stats() delete_btn.clicked.connect(delete_selected) def import_file(): path, _ = QtWidgets.QFileDialog.getOpenFileName(self, "Select file to import", "", "Текстовые файлы (*.txt)") if path: # Запуск импортера в отдельном потоке self.import_worker = ImportWorker(self.manager, section, path) self.import_thread = QtCore.QThread() self.import_worker.moveToThread(self.import_thread) self.import_worker.progress.connect(self.on_import_progress) self.import_worker.finished.connect(self.on_import_finished) self.import_thread.started.connect(self.import_worker.run) self.import_worker.finished.connect(self.import_thread.quit) self.import_worker.finished.connect(self.import_worker.deleteLater) self.import_thread.finished.connect(self.import_thread.deleteLater) # Сохраним текущий виджет и list_widget для обновления позже self.current_list_widget = list_widget # Блокируем интерфейс кнопок на время импорта add_btn.setEnabled(False) delete_btn.setEnabled(False) import_btn.setEnabled(False) entry_line.setEnabled(False) search_line.setEnabled(False) self.import_thread.start() import_btn.clicked.connect(import_file) self.pages[section] = widget self.stack.addWidget(widget) def on_import_progress(self, percent): self.statusBar().showMessage(f"Importing... {percent}%") def on_import_finished(self, count_added): self.statusBar().clearMessage() # Разблокируем интерфейс for section in ['emails', 'usernames', 'names', 'phones']: if self.stack.currentWidget() == self.pages[section]: widget = self.pages[section] for w in widget.findChildren(QtWidgets.QPushButton): w.setEnabled(True) for w in widget.findChildren(QtWidgets.QLineEdit): w.setEnabled(True) if count_added == -1: QtWidgets.QMessageBox.warning(self, "Error", "Cannot read the file. Please check the file format.") return if count_added > 0: # Обновляем список self.current_list_widget.clear() self.current_list_widget.addItems(self.manager.data[self.stack.currentWidget().findChild(QtWidgets.QLabel).text().lower()]) self.update_stats() QtWidgets.QMessageBox.information(self, "Import", f"Succes, Lines imported: {count_added}") else: QtWidgets.QMessageBox.information(self, "Import", f"Could not add any new lines. All entries already exist in the database.") def main(): app = QtWidgets.QApplication([]) window = HackerStyleDBApp() window.show() app.exec() if __name__ == "__main__": main() Сути нету просто говно код