<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Il giorno sab 9 mar 2019 alle ore 23:22 John F Sturtz <<a href="mailto:john@sturtz.org">john@sturtz.org</a>> ha scritto:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div id="gmail-m_-4362708302900851793__MailbirdStyleContent" style="font-size:12pt;font-family:Candara;color:rgb(0,0,0)"><div>(<i><a href="mailto:maurizio.berti@gmail.com" target="_blank">maurizio.berti@gmail.com</a></i>, if you're reading this, you'll probably recognize it.  I finally decided to implement this using separate widgets, <span style="font-family:"Courier New"">QLineEdit</span> for the user input and <span style="font-family:"Courier New"">QLabel</span> for the auto-completion, instead of using a <span style="font-family:"Courier New"">QTextEdit</span> for all of it per your suggestion.  I realize there is a <span style="font-family:"Courier New"">QCompleter</span> class that can be used with a <span style="font-family:"Courier New"">QLineEdit</span>, but I'm intent on implementing it myself.)</div></div></blockquote><div><br></div><div>Hello again John :-)<br>I'm not a big fan of "reinventing the wheel", as I tried to do that a lot of times, and those "lot of times" I realized that once you've deeper knowledge and experience with a framework (in this case, Qt) using its tools is usually better.</div><div>But. Sometimes having "control" over things *is* better, for various reasons. In this particular scenario I may agree with you. I don't like the QCompleter implementation a lot: even if it suits most user cases, its customization is problematic, expecially for special cases where there is the need for better UX response (like in your case, which involves some things QLineEdit doesn't provide, as inline formatting).</div><div>Implementing the QTextEdit wouldn't be that much easier indeed, as it would require *good* QSyntaxHighlighter programming and debugging, and probably the same amount of coding (considering the effort of time and "mental energy") you'll put in for font metrics issues and possible character/cursor positioning.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div id="gmail-m_-4362708302900851793__MailbirdStyleContent" style="font-size:12pt;font-family:Candara;color:rgb(0,0,0)"><div><span style="font-size:12pt">The issue is that the </span><span style="font-size:12pt;font-family:"Courier New"">QLabel</span><span style="font-size:12pt"> doesn't position itself properly at the end of what the user has typed in.  I am using </span><span style="font-size:12pt;font-family:"Courier New"">fontMetrics().horizontalAdvance(text)</span><span style="font-size:12pt"> on the text the user has typed in, to determine where to position the </span><span style="font-size:12pt;font-family:"Courier New"">Qlabel</span><span style="font-size:12pt">.  According to the documentation, that should be "</span><span style="font-size:12pt;line-height:1.5">the distance appropriate for drawing a subsequent character after </span><i style="font-size:12pt;line-height:1.5">text</i><span style="font-size:12pt;line-height:1.5">."  But it comes out too close to the preceding text.</span></div></div></blockquote><div><br></div><div>Unfortunately I'm still on Qt 5.7 (my main project is a bit critical, upgrading PyQt5 now would demand a lot of dependency issues that would put it at risk, as it's PyQt4 based), this means that I horizontalAdvance() isn't available for me as it was introduced in Qt 5.11.</div><div>Nonetheless, by using the "simpler" QFontMetrics.width() I got almost the same result, even if not probably "pixel-perfect" (it could depend on the font rendering hints used for the current font we're using, some updates in the rendering engine, png compression, etc).</div><div><br></div><div>That said, the issue here is that you didn't take into account the margins applied to the QLineEdit contents, which requires some QStyle work.</div><div>The first thing to look for is the subElementRect of QStyle.SE_LineEditContents, which returns the rectangle inside of which the text rendering happens: while QLineEdit does not inherit from QFrame as QLabels do, it still uses the QStyleOptionFrame (as it actually is some sort of "frame", with its borders and margins).</div><div>After that, QLineEdit adds its own margin to the text, which seems to be hardcoded and set to 2 (according to <a href="https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlineedit_p.cpp.html#QLineEditPrivate::horizontalMargin">https://code.woboq.org/qt5/qtbase/src/widgets/widgets/qlineedit_p.cpp.html#QLineEditPrivate::horizontalMargin</a> ).</div><div>Finally, while in most uses this could be enough, remember that you're using two very different widgets that apply some margins to their contents whenever they're drawn. Luckily, the QLabel doesn't seem to apply further margins using default QStyle(s) on Linux, but it might be better to check for the QLabel's option too. This may also be necessary in some cases where the QLabel vertical positioning is different from QLineEdit, again depending on the current QStyle (I think it might the case of the default styles used on Windows and MacOS).<br></div><div><br></div><div>I've just added some lines to your code, and it seems to be all right also while zooming in (even with QFontMetrics.width() instead of horizontalAdvance):</div><div><br></div><div><div><font face="monospace, monospace">        # Position display widget</font></div><div><font face="monospace, monospace">        option = QtWidgets.QStyleOptionFrame()</font></div><div><font face="monospace, monospace">        self.initStyleOption(option)</font></div><div><font face="monospace, monospace">        rect = self.style().subElementRect(QtWidgets.QStyle.SE_LineEditContents, option, self)</font></div><div><font face="monospace, monospace">        # Add the left position of the contents and the hardcoded horizontalMargin of QLineEdit</font></div><div><font face="monospace, monospace">        w.move(self.fontMetrics().width(user) + rect.left() + 2, 0)</font></div></div><div><br></div><div>As a side note, remember to be careful about variable and property naming: you used <font face="monospace, monospace">self.style</font> for the stylesheet, but <font face="monospace, monospace">style()</font> is an important property of QWidgets: I had to change it to have a direct reference to it, otherwise I'd have to use super/QtWidgets.QLabel.style(self).</div><div><br></div><div><br></div><div>Cheers,</div><div>Maurizio</div><div><br></div></div>-- <br><div dir="ltr" class="gmail_signature">È difficile avere una convinzione precisa quando si parla delle ragioni del cuore. - "Sostiene Pereira", Antonio Tabucchi<br><a href="http://www.jidesk.net" target="_blank">http://www.jidesk.net</a></div></div></div></div></div></div>