Tribler / tribler

Privacy enhanced BitTorrent client with P2P content discovery
https://www.tribler.org
GNU General Public License v3.0
4.8k stars 444 forks source link

Rewrite the GUI to use a Qt webview (HTML+Javascript) #7736

Closed qstokkink closed 1 month ago

qstokkink commented 10 months ago

Currently, our GUI uses a mix of Qt XML (QML), custom Qt Python widgets and CSS. Modifying or extending this XML (which can be up to 6000 lines) is rather painful. Furthermore, implementing custom Python Qt widgets takes a lot of time and tends to be error-prone, just for the end-goal of reinventing the wheel to mimick common web interfaces.

We can downsize and simplify our code base by switching from XML+custom Python to HTML and Javascript. The latter combo has very mature (and bug free!) libraries. We can make this switch relatively easily and without sacrificing features by using Qt's WebViews, which allows us to keep tray icons etc.

As an aside, more people understand HTML and Javascript so this should also make it easier for developers to contribute to our code base.

drew2a commented 10 months ago

From my very first day of working with Tribler, I believed that we should change our direction towards HTML and Javascript. The way QT is used in Tribler has led to the fact that none of the developers want to (and sometimes can) work with it. This leads to us not changing our UI and not fixing bugs in the GUI, preferring instead to work with the core.

Our GUI does not look quite attractive. To make it attractive, we should spend a lot of effort. Having a lot of effort to make on one hand and no wish from developers to apply this effort on the other hand means the Tribler GUI in QT will never be good.

In contrast, if you choose HTML+Javascript, you have so many templates that will make the UI look and feel cool and modern with almost no effort from the developer's side.

So, @qstokkink you have my full support on this topic.

egbertbouman commented 10 months ago

We have some old (Angular) prototypes: https://github.com/egbertbouman/tribler-webui for the main UI https://github.com/egbertbouman/tribler-debug-ui for the debug panel

synctext commented 10 months ago

Big investment in het past of re-writing our wxPython in favor of PyQt. Adding Javascript is something I would like to avoid, but we're living in modern times. Just QT +Webviewer + Javascript seems "clean" on our 3 supported OSes.

https://stackoverflow.com/questions/34184704/qwebview-not-loading-external-javascript

    QString html = readFile(":/qt.html");
    view->setHtml(html, QUrl("qrc:/"));

application.qrc

<!DOCTYPE RCC><RCC version="1.0">
<qresource>
    <file alias="qt.png">resource/qt.png</file>
    <file alias="image.html">resource/image.html</file>
    <file alias="qt.html">resource/qt.html</file>
    <file alias="qt.js">resource/qt.js</file>
</qresource>
</RCC>
qstokkink commented 9 months ago

I used a spare 5 minutes to hook in @egbertbouman's debug UI:

# Install the Python API
pip install git+ssh://git@github.com/egbertbouman/tribler-debug-ui.git/

# Pull in the latest release
UIDIR="$(pip show tribler-debug-ui | sed -n "/Location: /s/Location: //p")"
wget https://github.com/egbertbouman/tribler-debug-ui/archive/refs/tags/v7.6.0.zip
unzip v7.6.0.zip 'tribler-debug-ui-7.6.0/*' -d "$UIDIR/tribler_debug_ui"
mv "$UIDIR/tribler_debug_ui/tribler-debug-ui-7.6.0" "$UIDIR/tribler_debug_ui/app"
rm -r "$UIDIR/tribler_debug_ui/tribler-debug-ui-master"
rm v7.6.0.zip
Tribler patch file ```patch diff --git a/src/tribler/core/components/restapi/restapi_component.py b/src/tribler/core/components/restapi/restapi_component.py index a43ff2bdf..19c452266 100644 --- a/src/tribler/core/components/restapi/restapi_component.py +++ b/src/tribler/core/components/restapi/restapi_component.py @@ -2,6 +2,8 @@ from itertools import chain from typing import Type from ipv8.REST.root_endpoint import RootEndpoint as IPV8RootEndpoint +from tribler_debug_ui.endpoint import DebugUIEndpoint + from tribler.core.components.bandwidth_accounting.bandwidth_accounting_component import BandwidthAccountingComponent from tribler.core.components.bandwidth_accounting.restapi.bandwidth_endpoint import BandwidthEndpoint from tribler.core.components.component import Component @@ -36,6 +38,10 @@ from tribler.core.components.tunnel.tunnel_component import TunnelsComponent from tribler.core.utilities.unicode import hexlify +class TriblerDebugUIEndpoint(DebugUIEndpoint): + path = "/debugui" + + class RESTComponent(Component): rest_manager: RESTManager = None root_endpoint: RootEndpoint = None @@ -105,6 +111,7 @@ class RESTComponent(Component): tag_rules_processor=knowledge_component.rules_processor) self.maybe_add(SearchEndpoint, content_discovery_component.community) self.maybe_add(KnowledgeEndpoint, db=db_component.db, community=knowledge_component.community) + self.maybe_add(TriblerDebugUIEndpoint, session=None) if not isinstance(ipv8_component, NoneComponent): ipv8_root_endpoint = IPV8RootEndpoint() diff --git a/src/tribler/gui/debug_window.py b/src/tribler/gui/debug_window.py index c6544dc77..f50340b12 100644 --- a/src/tribler/gui/debug_window.py +++ b/src/tribler/gui/debug_window.py @@ -11,8 +11,9 @@ from typing import Dict import libtorrent import psutil from PyQt5 import QtGui, uic -from PyQt5.QtCore import QTimer, Qt, pyqtSignal +from PyQt5.QtCore import QTimer, Qt, pyqtSignal, QUrl from PyQt5.QtGui import QBrush, QColor, QTextCursor +from PyQt5.QtWebEngineWidgets import QWebEngineView from PyQt5.QtWidgets import QDesktopWidget, QFileDialog, QHeaderView, QMainWindow, QMessageBox, QTreeWidgetItem from tribler.core.utilities.utilities import has_bep33_support @@ -51,6 +52,18 @@ class CPUPlot(TimeSeriesPlot): class DebugWindow(QMainWindow): + + def __init__(self, settings, gui_settings, tribler_version): + QMainWindow.__init__(self) + + we_view = QWebEngineView(self) + port = settings['api']['http_port'] + we_view.setUrl(QUrl(f"http://127.0.0.1:{port}/debugui/?apikey={settings['api']['key']}")) + self.setCentralWidget(we_view) + self.setGeometry(0, 0, 640, 480) + + +class DebugWindowOld(QMainWindow): """ The debug window shows various statistics about Tribler such as performed requests, IPv8 statistics and community information. ```

Looking almost functional already. I think the endpoints may still be hooked up wrong though because I'm not seeing any data.

screenshot

synctext commented 9 months ago

Very impressive! Now we can even incrementally deploy this big change. First EgbertAngular debug screen and install scripts. Later full Tribler. Tentatively scheduled when the new ClickLog, randevouz, and Simple MeritRank are finished. Plus do website makeover. Website same style as GUI, hire an actual professional designer.

ichorid commented 9 months ago

I'd say go even further, the same way Deluge and other clients do: don't even use QT WebView, just display the UI directly in the system browser. That way, you will only need a tray icon for managing the Core, and skip all the problems associated with running QT for GUI altogether. Also, you get all the modern Web UI testing frameworks, e.g. Selenium.

jkaberg commented 6 months ago

I'd say go even further, the same way Deluge and other clients do: don't even use QT WebView, just display the UI directly in the system browser. That way, you will only need a tray icon for managing the Core, and skip all the problems associated with running QT for GUI altogether. Also, you get all the modern Web UI testing frameworks, e.g. Selenium.

I'd like to add an +1 to this comment; This is the modern way of doing these things, Tribler can be seen as an alternative to Deluge, qBittorrent etc which I think in 9 out of 10 cases will run on headless servers. There is an big upside to support headless devices due to the distributed nature of the Tribler network (headless are more often left alone/online than typical desktop devices - and thus serves the network in an better way)

egbertbouman commented 5 months ago

I've started working on a new web interface in React:

tribler_webui_dark

And light mode:

tribler_webui_light

Things are nowhere near completed, and once it is it's probably going to be deployed in Tribler Experimental first. So, we'll still be using Qt for the time being.

qstokkink commented 1 month ago

This issue has been resolved. 🚀