0

I am able to display an HTML file using PyQt, but I have not found a way to apply CSS properties to this HTML. From what I have read, it seems that QSS can be used to change the appearance of QWidgets (which I am not using), and from my tests, it does not seem to have any effect on HTML.

I attempted to use setStyleSheet with both a .css file and a .qss file, but the effect was not applied in either case. I checked that my CSS syntax is correct by creating a Live Server with the .html file normally, and it was as I expected (with the "words" element having its background turned red). I guessing that the QSS is correct since qtsass.compile(open(websiteSource + "style.scss").read()) does not throw an "Invalid CSS" error, which it did when I was inputting a .sass file instead of .scsss, but I don't really know.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1 id="words">Test</h1>
</body>
</html>

style.css

#words {
    background-color: red;
}

style.qss

#words {
  background-color: red; }

Attempting to use CSS

from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWebEngineWidgets import QWebEngineView
import os

app = QApplication([os.path.basename(__file__)])
window = QWidget()
layout = QVBoxLayout()
websiteSource = "C:/Users/mikei/OneDrive/Documents/GeneralWebsite/Test6/"
 
view = QWebEngineView()
layout.addWidget(view)
 
view.setHtml(open(websiteSource + "index.html").read())

window.setLayout(layout)
window.show()

def on_load_finished(): 
     app.setStyleSheet(open(websiteSource + "style.css").read())

view.loadFinished.connect(on_load_finished)

app.exec()

Attempting to use QSS (generated from the CSS file)

from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt6.QtWebEngineWidgets import QWebEngineView
import os
import http.client
import urllib.parse
import json
import qtsass

app = QApplication([os.path.basename(__file__)])
window = QWidget()
layout = QVBoxLayout()
websiteSource = "C:/Users/mikei/OneDrive/Documents/GeneralWebsite/Test6/"


#Converts CSS to SCSS
conn = http.client.HTTPSConnection("css2sass.herokuapp.com")
source = open(websiteSource + "style.css").read()
safe_string = urllib.parse.quote(source)

payload = ""
headers = { 'cookie': "rack.session=BAh7CEkiD3Nlc3Npb25faWQGOgZFVG86HVJhY2s6OlNlc3Npb246OlNlc3Npb25JZAY6D0BwdWJsaWNfaWRJIkViNDJkMzM0N2UzNDQ1N2U5MDRlNjkyYzk2M2U3OTA0ZDBlOWRmYWFlOTYxNzNhMDIwOGVkZTM2ODUxY2Q4OTJiBjsARkkiCWNzcmYGOwBGSSIxZGo4cXRlQ1FBMDdZa1Q0ckNTOXlNeE1QR1Nid2pMMER6Y0pFSGtqcDhNaz0GOwBGSSINdHJhY2tpbmcGOwBGewZJIhRIVFRQX1VTRVJfQUdFTlQGOwBUSSItYjliNTMwNzkwZDU5MmQyNjk1MmU1YmQ0NGRjODA5M2JhMDU2NzBmZgY7AEY%253D" }

conn.request("POST", "/?css="+safe_string+"&type=scss", payload, headers)

res = conn.getresponse()
data = res.read()
data = json.loads(data.decode("utf-8"))

sass = open(websiteSource + "style.scss", "w")
sass.write(data["output"])
sass.close()
print(data["output"])

#Converts SCSS to QSS
qtsas = qtsass.compile(open(websiteSource + "style.scss").read())

newQSS = open(websiteSource + "style.qss", 'w')
newQSS.write(qtsas)
newQSS.close()

#The actual window stuff
view = QWebEngineView()
layout.addWidget(view)
 
view.setHtml(open(websiteSource + "index.html").read())

window.setLayout(layout)
window.show()

print(open(websiteSource + "style.qss").read())
def on_load_finished(): 
    app.setStyleSheet(open(websiteSource + "style.qss").read())

view.loadFinished.connect(on_load_finished)

app.exec()
  • You *are* using widgets: the fact that you don't see buttons or input fields is irrelevant; both `QWidget.setStyleSheet()` and `QApplication.setStyleSheet()` only apply qss to the appearance of widgets and has absolutely **no** effect on the html contents of a web view. That's for two reasons: 1. QSS are **not** CSS (they only share their concepts and syntax); 2. a QSS must not (nor can) affect the appearance of a web page, since it shows its contents using a web engine (which *does* follow web standards, including *actual* css). The fact that qtsass doesn't show any error is just due to » – musicamante Aug 20 '23 at 11:19
  • » the fact that the syntax of your css file is valid both as CSS and from the QSS perspective. Now, the question is: what are you trying to do? If you want to have separated *local* HTML and CSS files there's really no point in using `setHtml()`, just use `setUrl()` or `load()`. If you want to override the CSS of any page (local, dynamically created or remote), then you have to "inject" the CSS using a script. – musicamante Aug 20 '23 at 11:27
  • 2
    As explained in the [docs for setHtml](https://doc.qt.io/qt-6/qwebengineview.html#setHtml), you may need to use the `baseUrl` parameter in order to ensure external resources load correctly. – ekhumoro Aug 20 '23 at 11:32
  • @musicamante Changing from setHtml() to load() fixed my issue, but I am not seeing a way to close this question without an Answer, so should this question just be left open, should I give it an Answer saying what you said, or should you Answer it because your answer was the solution? – HereForABit Aug 20 '23 at 16:23

0 Answers0