mirror of
https://github.com/khoj-ai/khoj.git
synced 2025-02-17 08:04:21 +00:00
Open Web interface within Desktop app in GUI mode (#429)
Previously the GUI mode (with khoj --gui or using the desktop app) would open the web interface in the users default web browser. Now the web interface is just rendered within the app itself using PyQT's Webview. This gives it a more proper app like feel
This commit is contained in:
commit
14a816d173
4 changed files with 33 additions and 43 deletions
|
@ -24,7 +24,7 @@ For more detailed Windows installation and troubleshooting, see [Windows Install
|
|||
|
||||
### 2. Start
|
||||
|
||||
Run the following command from your terminal to start the Khoj backend and open Khoj in your browser.
|
||||
Run the following command in your terminal to start the Khoj backend and open the Khoj native GUI
|
||||
|
||||
```shell
|
||||
khoj --gui
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
# Standard Packages
|
||||
import webbrowser
|
||||
|
||||
# External Packages
|
||||
from PySide6 import QtGui, QtWidgets
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6 import QtGui
|
||||
from PySide6.QtCore import Qt, QThread, QUrl
|
||||
from PySide6.QtWebEngineWidgets import QWebEngineView
|
||||
from PySide6.QtWebEngineCore import QWebEnginePage
|
||||
|
||||
# Internal Packages
|
||||
from khoj.utils import constants
|
||||
from PySide6.QtCore import QThread
|
||||
|
||||
|
||||
class ServerThread(QThread):
|
||||
|
@ -22,11 +20,12 @@ class ServerThread(QThread):
|
|||
self.start_server_func()
|
||||
|
||||
|
||||
class MainWindow(QtWidgets.QMainWindow):
|
||||
class MainWindow(QWebEngineView):
|
||||
"""Create Window to Navigate users to the web UI"""
|
||||
|
||||
def __init__(self, host: str, port: int):
|
||||
def __init__(self, url: str):
|
||||
super(MainWindow, self).__init__()
|
||||
self.base_url = url
|
||||
|
||||
# Initialize Configure Window
|
||||
self.setWindowTitle("Khoj")
|
||||
|
@ -35,25 +34,23 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
icon_path = constants.web_directory / "assets/icons/favicon-128x128.png"
|
||||
self.setWindowIcon(QtGui.QIcon(f"{icon_path.absolute()}"))
|
||||
|
||||
# Initialize Configure Window Layout
|
||||
self.wlayout = QtWidgets.QVBoxLayout()
|
||||
# Open Khoj Web App Root
|
||||
self.webpage = QWebEnginePage()
|
||||
self.setPage(self.webpage)
|
||||
self.webpage.load(QUrl(self.base_url))
|
||||
|
||||
# Add a Label that says "Khoj Configuration" to the Window
|
||||
self.wlayout.addWidget(QtWidgets.QLabel("Welcome to Khoj"))
|
||||
|
||||
# Add a Button to open the Web UI at http://host:port/config
|
||||
self.open_web_ui_button = QtWidgets.QPushButton("Open Web UI")
|
||||
self.open_web_ui_button.clicked.connect(lambda: webbrowser.open(f"http://{host}:{port}/config"))
|
||||
|
||||
self.wlayout.addWidget(self.open_web_ui_button)
|
||||
|
||||
# Set the central widget of the Window. Widget will expand
|
||||
# to take up all the space in the window by default.
|
||||
self.config_window = QtWidgets.QWidget()
|
||||
self.config_window.setLayout(self.wlayout)
|
||||
self.setCentralWidget(self.config_window)
|
||||
self.position_window()
|
||||
|
||||
def show_page(self, page: str = "", maximized=False):
|
||||
def load_page():
|
||||
self.webpage.load(QUrl(f"{self.base_url}/{page}"))
|
||||
if maximized:
|
||||
self.showMaximized()
|
||||
else:
|
||||
self.show()
|
||||
|
||||
return load_page
|
||||
|
||||
def position_window(self):
|
||||
"Position the window at center of X axis and near top on Y axis"
|
||||
window_rectangle = self.geometry()
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
# Standard Packages
|
||||
import webbrowser
|
||||
|
||||
# External Packages
|
||||
from PySide6 import QtGui, QtWidgets
|
||||
|
||||
# Internal Packages
|
||||
from khoj.utils import constants, state
|
||||
from khoj.utils import constants
|
||||
from khoj.interface.desktop.main_window import MainWindow
|
||||
|
||||
|
||||
|
@ -25,9 +22,9 @@ def create_system_tray(gui: QtWidgets.QApplication, main_window: MainWindow):
|
|||
# Create the menu and menu actions
|
||||
menu = QtWidgets.QMenu()
|
||||
menu_actions = [
|
||||
("Search", lambda: webbrowser.open(f"http://{state.host}:{state.port}/")),
|
||||
("Configure", lambda: webbrowser.open(f"http://{state.host}:{state.port}/config")),
|
||||
("App", main_window.show),
|
||||
("Search", main_window.show_page()),
|
||||
("Chat", main_window.show_page("chat")),
|
||||
("Configure", main_window.show_page("config")),
|
||||
("Quit", gui.quit),
|
||||
]
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@ import logging
|
|||
import threading
|
||||
import warnings
|
||||
from platform import system
|
||||
import webbrowser
|
||||
|
||||
# Ignore non-actionable warnings
|
||||
warnings.filterwarnings("ignore", message=r"snapshot_download.py has been made private", category=FutureWarning)
|
||||
|
@ -85,8 +84,9 @@ def run():
|
|||
from khoj.interface.desktop.system_tray import create_system_tray
|
||||
|
||||
# Setup GUI
|
||||
url = f"http://{args.host}:{args.port}"
|
||||
gui = QtWidgets.QApplication([])
|
||||
main_window = MainWindow(args.host, args.port)
|
||||
main_window = MainWindow(url)
|
||||
|
||||
# System tray is only available on Windows, MacOS.
|
||||
# On Linux (Gnome) the System tray is not supported.
|
||||
|
@ -102,17 +102,13 @@ def run():
|
|||
configure_routes(app)
|
||||
server = ServerThread(start_server_func=lambda: start_server(app, host=args.host, port=args.port))
|
||||
|
||||
url = f"http://{args.host}:{args.port}"
|
||||
logger.info(f"🌗 Khoj is running at {url}")
|
||||
try:
|
||||
startup_url = url if args.config else f"{url}/config"
|
||||
webbrowser.open(startup_url)
|
||||
except:
|
||||
logger.warning(f"🚧 Unable to open browser. Please open {url} manually to configure or use Khoj.")
|
||||
|
||||
# Show Main Window on First Run Experience or if on Linux
|
||||
if args.config is None or system() not in ["Windows", "Darwin"]:
|
||||
main_window.show()
|
||||
# Show config window on first run and main window otherwise
|
||||
startup_window = (
|
||||
main_window.show_page(maximized=True) if args.config else main_window.show_page("config", maximized=True)
|
||||
)
|
||||
startup_window()
|
||||
|
||||
# Setup Signal Handlers
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
|
|
Loading…
Add table
Reference in a new issue