Reputation: 27574
HtmlEditor is meant to be empty, editable and display only one line at first. Its height is just enough to hold one line, no more bigger or smaller. The height of it will extend as the user inputs more lines of text.
But the problem is, the height of HtmlEditor is a little smaller at first. I guess it is because the height is set to be exactly the size of the font, but there are also margins around the font too, which isn't considered. After inputting a character in it, the height of HtmlEditor will soon get bigger, just enough to hold the text thanks to the sizeChange
function. I wish I could set the MaximumHeight of HtmlEditor as self.page().mainFrame().contentsSize().height()
at first too, because contentsSize().height()
seems perfect to hold the text. But it seems impossible considering there is no contents at all at first, in which case contentsSize().height()
is just a wrong number. How to do the trick, setting both MaximumHeight and MinimumHeight of HtmlEditor as the height of the contents to just hold it?
class HtmlEditor(QWebView):
def __init__(self):
super().__init__()
self.page().setContentEditable(True)
self.page().contentsChanged.connect(self.sizeChange)
self.setUpFont(10)
def setUpFont(self, fontSize):
self.htmlEditorSettings = self.settings()
self.htmlEditorSettings.setFontSize(QWebSettings.DefaultFontSize, fontSize)
self.setMaximumHeight(fontSize)
def sizeChange(self):
docHeight = self.page().mainFrame().contentsSize().height()
self.setMinimumHeight(docHeight)
Upvotes: 0
Views: 343
Reputation: 27574
Thank @MichaelBlakeley, this is my final code:
class HtmlEditor(QWebView):
def __init__(self):
super().__init__()
self.page().setContentEditable(True)
self.page().contentsChanged.connect(self.sizeChange)
self.setupFont(10)
def setupFont(self, fontSize):
self.htmlEditorSettings = self.settings()
self.htmlEditorSettings.setFontSize(QWebSettings.DefaultFontSize, fontSize)
margins = self.contentsMargins()
self.setFixedHeight(fontsize + margins.top() + margins.bottom())
def sizeChange(self):
docHeight = self.page().mainFrame().contentsSize().height()
self.setFixedHeight(docHeight)
Upvotes: 0
Reputation: 346
Here is a hackish solution using QFontMetrics. I'm considering it hackish since I had to implement the text leading manually. There's probably a good reason why QFontMetrics
seems to be spitting out a bad value, but this should work for you in the mean time.
We take all of the sizing information for a line of text, figure out how many lines we're working with, and adjust the size of QWebView
accordingly:
class HtmlEditor(QWebView):
def __init__(self):
super().__init__()
self.page().setContentEditable(True)
self.page().contentsChanged.connect(self.update_height)
self.settings().setFontSize(QWebSettings.DefaultFontSize, 10)
self.setContentsMargins(QMargins(10, 10, 10, 10))
self.update_height()
def update_height(self):
num_lines = len(self.page().mainFrame().toPlainText().splitlines())
if num_lines == 0:
num_lines = 1
margins = self.contentsMargins()
metrics = self.fontMetrics()
leading = 4 # You should be able to do metrics.leading() but it was giving me 0 for some reason
line_height = metrics.height() # For the above reason, we use height() here instead of metrics.lineSpacing() and add the leading manually
self.setFixedHeight((line_height * num_lines) + (leading * (num_lines - 1)) + margins.top() + margins.bottom())
I would be greatly appreciative if somebody could chime in here with a reasoning for the strange behavior of QFontMetrics
in this scenario.
Upvotes: 1