Remove PySide from main

This commit is contained in:
2026-05-05 16:05:24 +03:00
parent 9a8cdfa08a
commit 16a7fb32fd
79 changed files with 0 additions and 80830 deletions
Binary file not shown.
Binary file not shown.
-64
View File
@@ -1,64 +0,0 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'mainwindow.ui'
##
## Created by: Qt User Interface Compiler version 6.11.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QMainWindow, QPushButton,
QSizePolicy, QWidget)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(640, 480)
MainWindow.setStyleSheet(u"background-color: qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:0, stop:0 rgba(81, 0, 135, 255), stop:0.427447 rgba(41, 61, 132, 235), stop:1 rgba(155, 79, 165, 255))")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.widget = QWidget(self.centralwidget)
self.widget.setObjectName(u"widget")
self.widget.setGeometry(QRect(10, 10, 621, 51))
self.horizontalLayout = QHBoxLayout(self.widget)
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.pushButton = QPushButton(self.widget)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setMouseTracking(False)
self.horizontalLayout.addWidget(self.pushButton)
self.pushButton_2 = QPushButton(self.widget)
self.pushButton_2.setObjectName(u"pushButton_2")
self.horizontalLayout.addWidget(self.pushButton_2)
self.pushButton_3 = QPushButton(self.widget)
self.pushButton_3.setObjectName(u"pushButton_3")
self.horizontalLayout.addWidget(self.pushButton_3)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"LAIC Local AI Character", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"\u0421\u043f\u0438\u0441\u043e\u043a \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u0439", None))
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"\u041f\u0440\u043e\u0444\u0438\u043b\u044c", None))
self.pushButton_3.setText(QCoreApplication.translate("MainWindow", u"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u043d\u0444\u0435\u0440\u0435\u043d\u0441\u0430", None))
# retranslateUi
-60
View File
@@ -1,60 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>LAIC Local AI Character</string>
</property>
<property name="styleSheet">
<string notr="true">background-color: qlineargradient(spread:pad, x1:1, y1:1, x2:0, y2:0, stop:0 rgba(81, 0, 135, 255), stop:0.427447 rgba(41, 61, 132, 235), stop:1 rgba(155, 79, 165, 255))</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>621</width>
<height>51</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="text">
<string>Список персонажей</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Профиль</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Настройки инференса</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
-287
View File
@@ -1,287 +0,0 @@
from PySide6.QtWidgets import (QMainWindow, QDialog, QVBoxLayout, QHBoxLayout, QLabel,
QPushButton, QListWidget, QListWidgetItem, QWidget,
QTextEdit, QLineEdit)
from PySide6.QtCore import Qt, QThread, Signal
from PySide6.QtGui import QPixmap
from core.ui.mainwindow import Ui_MainWindow
from core.agent.agent import Agent
from core.character.character import Character
from core.llm.ollamaapi import OllamaProvider
class CharacterListDialog(QDialog):
"""Диалоговое окно со списком персонажей"""
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Выбор персонажа")
self.setMinimumSize(500, 400)
self.selected_character = None
layout = QVBoxLayout(self)
# Заголовок
title = QLabel("Выберите персонажа:")
title.setStyleSheet("font-size: 16px; font-weight: bold;")
layout.addWidget(title)
# Список персонажей
self.list_widget = QListWidget()
self.list_widget.itemDoubleClicked.connect(self.select_character)
layout.addWidget(self.list_widget)
# Кнопки
btn_layout = QHBoxLayout()
select_btn = QPushButton("Выбрать")
select_btn.clicked.connect(self.select_character)
btn_layout.addWidget(select_btn)
close_btn = QPushButton("Отмена")
close_btn.clicked.connect(self.close)
btn_layout.addWidget(close_btn)
layout.addLayout(btn_layout)
self.load_characters()
def load_characters(self):
"""Загружает список персонажей"""
characters = Agent.get_all_char_info()
for char in characters:
item = QListWidgetItem()
item.setData(Qt.UserRole, char) # Сохраняем данные персонажа
# Создаём кастомный виджет для строки списка
widget = QWidget()
widget.setFixedHeight(60)
widget_layout = QHBoxLayout(widget)
widget_layout.setContentsMargins(5, 5, 5, 5)
# Аватар
avatar_label = QLabel()
avatar_label.setFixedSize(60, 60)
avatar_path = char.get('avatar_path')
if avatar_path:
pixmap = QPixmap(avatar_path)
if not pixmap.isNull():
avatar_label.setPixmap(pixmap.scaled(60, 60, Qt.KeepAspectRatio, Qt.SmoothTransformation))
else:
avatar_label.setText("")
avatar_label.setAlignment(Qt.AlignCenter)
else:
avatar_label.setText("Нет")
avatar_label.setAlignment(Qt.AlignCenter)
widget_layout.addWidget(avatar_label)
# Имя и ID
name = char.get('name', 'Без имени')
char_id = char.get('id', 'N/A')
info_label = QLabel(f"<b>{name}</b><br><small>ID: {char_id}</small>")
info_label.setTextFormat(Qt.RichText)
widget_layout.addWidget(info_label)
widget_layout.addStretch()
self.list_widget.addItem(item)
self.list_widget.setItemWidget(item, widget)
def select_character(self):
"""Выбирает персонажа и закрывает диалог"""
current_item = self.list_widget.currentItem()
if current_item:
self.selected_character = current_item.data(Qt.UserRole)
self.accept() # Закрывает диалог с кодом Accepted
class GenerationThread(QThread):
"""Поток для генерации ответа (чтобы не блокировать UI)"""
response_ready = Signal(str)
error_occurred = Signal(str)
def __init__(self, agent, user_input):
super().__init__()
self.agent = agent
self.user_input = user_input
def run(self):
try:
response = self.agent.respond(self.user_input)
self.response_ready.emit(response)
except Exception as e:
self.error_occurred.emit(str(e))
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
# Состояние приложения
self.current_agent = None
self.current_character = None
self.generation_thread = None
# Настройка UI
self.setup_chat_ui()
# Подключение кнопок
self.ui.pushButton.clicked.connect(self.show_character_list)
self.ui.pushButton_2.clicked.connect(self.show_profile)
self.ui.pushButton_3.clicked.connect(self.show_settings)
def setup_chat_ui(self):
"""Настраивает UI чата"""
# Находим centralwidget и добавляем чат
self.chat_widget = self.ui.centralwidget
# Создаём вертикальный layout для centralwidget
chat_layout = QVBoxLayout(self.chat_widget)
chat_layout.setContentsMargins(10, 70, 10, 10) # Отступы сверху для кнопок
# Область чата (только чтение)
self.chat_display = QTextEdit()
self.chat_display.setReadOnly(True)
self.chat_display.setPlaceholderText("Выберите персонажа для начала чата...")
chat_layout.addWidget(self.chat_display)
# Панель ввода
input_layout = QHBoxLayout()
self.message_input = QLineEdit()
self.message_input.setPlaceholderText("Введите сообщение...")
self.message_input.returnPressed.connect(self.send_message)
input_layout.addWidget(self.message_input)
self.send_button = QPushButton("Отправить")
self.send_button.clicked.connect(self.send_message)
self.send_button.setEnabled(False) # До выбора персонажа недоступна
input_layout.addWidget(self.send_button)
chat_layout.addLayout(input_layout)
def show_character_list(self):
"""Показывает диалог выбора персонажа"""
dialog = CharacterListDialog(self)
if dialog.exec() == QDialog.Accepted and dialog.selected_character:
self.select_character(dialog.selected_character)
def select_character(self, char_data):
"""Выбирает персонажа и загружает его данные"""
char_id = char_data.get('id')
try:
# Загружаем персонажа
self.current_character = Character.load(char_id)
# Создаём агента (используем заглушку для LLM)
# В реальном приложении нужно выбрать модель
self.current_agent = Agent(
self.current_character,
OllamaProvider("qwen3-vl:8b"), # Модель по умолчанию
user_name="Gloomer"
)
# Загружаем память (историю чата)
self.current_agent.load_memory()
self.current_agent.ensure_first_message()
# Обновляем UI
self.update_chat_display()
self.send_button.setEnabled(True)
self.message_input.setEnabled(True)
self.message_input.setFocus()
# Показываем информацию о выбранном персонаже
self.chat_display.append(f"<b>Выбран персонаж:</b> {self.current_character.display_name}\n")
except Exception as e:
self.chat_display.append(f"<b>Ошибка загрузки персонажа:</b> {str(e)}\n")
def update_chat_display(self):
"""Обновляет отображение истории чата"""
if not self.current_agent:
return
self.chat_display.clear()
for msg in self.current_agent.chat_history:
role = msg.get('role', '')
content = msg.get('content', '')
if role == 'user':
self.chat_display.append(f"<b>Вы:</b> {content}\n")
elif role == 'assistant':
self.chat_display.append(f"<b>{self.current_character.name}:</b> {content}\n")
def send_message(self):
"""Отправляет сообщение и получает ответ"""
if not self.current_agent or not self.message_input.text().strip():
return
user_input = self.message_input.text().strip()
self.message_input.clear()
# Показываем сообщение пользователя
self.chat_display.append(f"<b>Вы:</b> {user_input}\n")
self.chat_display.append("<i>Думаю...</i>\n")
# Блокируем ввод на время генерации
self.message_input.setEnabled(False)
self.send_button.setEnabled(False)
# Запускаем генерацию в отдельном потоке
self.generation_thread = GenerationThread(self.current_agent, user_input)
self.generation_thread.response_ready.connect(self.on_response_ready)
self.generation_thread.error_occurred.connect(self.on_error)
self.generation_thread.start()
def on_response_ready(self, response):
"""Обрабатывает готовый ответ от LLM"""
# Удаляем "Думаю..."
cursor = self.chat_display.textCursor()
cursor.movePosition(cursor.Start)
cursor.select(cursor.LineUnderCursor)
cursor.removeSelectedText()
cursor.deleteChar() # Удаляем \n
# Показываем ответ
self.chat_display.append(f"<b>{self.current_character.name}:</b> {response}\n")
# Сохраняем память
self.current_agent.save_memory()
# Разблокируем ввод
self.message_input.setEnabled(True)
self.send_button.setEnabled(True)
self.message_input.setFocus()
def on_error(self, error_msg):
"""Обрабатывает ошибку генерации"""
self.chat_display.append(f"<b>Ошибка:</b> {error_msg}\n")
# Разблокируем ввод
self.message_input.setEnabled(True)
self.send_button.setEnabled(True)
self.message_input.setFocus()
def show_profile(self):
"""Показывает профиль персонажа (заглушка)"""
if self.current_character:
self.chat_display.append(f"<b>Профиль:</b> {self.current_character.display_name}\n")
else:
self.chat_display.append("<b>Сначала выберите персонажа</b>\n")
def show_settings(self):
"""Показывает настройки инференса (заглушка)"""
if self.current_character:
self.chat_display.append(
f"<b>Настройки:</b>\n"
f"- Temperature: {self.current_character.temperature}\n"
f"- Max Tokens: {self.current_character.max_tokens}\n"
)
else:
self.chat_display.append("<b>Сначала выберите персонажа</b>\n")