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()
4
  • 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 » Commented Aug 20, 2023 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. Commented Aug 20, 2023 at 11:27
  • 2
    As explained in the docs for setHtml, you may need to use the baseUrl parameter in order to ensure external resources load correctly. Commented Aug 20, 2023 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? Commented Aug 20, 2023 at 16:23

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.