Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minus-circle not working #97

Closed
flutefreak7 opened this issue Sep 24, 2018 · 16 comments · Fixed by #98
Closed

minus-circle not working #97

flutefreak7 opened this issue Sep 24, 2018 · 16 comments · Fixed by #98
Milestone

Comments

@flutefreak7
Copy link

flutefreak7 commented Sep 24, 2018

I'm on Windows 10 with PyQt5.

The following demo:

from PyQt5 import QtWidgets, QtGui, QtCore
import qtawesome as qta

app = QtWidgets.QApplication([])

icon = qta.icon('fa5s.minus-circle')

widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
button = QtWidgets.QPushButton()
button.setFixedHeight(100)
button.setIconSize(QtCore.QSize(100, 100))
button.setIcon(icon)
layout.addWidget(button)

widget.setLayout(layout)

widget.show()

app.exec_()

Gives me this:
image

@flutefreak7
Copy link
Author

Hmmm, there is more going on... user-minus is giving me an icon, just the wrong one...

image

@ccordoba12
Copy link
Member

@darkvertex, could you chime in here, please?

@darkvertex
Copy link
Contributor

@ccordoba12 yep...

(My Linux OS skin is dark, so forgive the dark screenshots.)

I'm on CentOS Linux at the moment. I tried the first code snippet with fa5s.minus-circle (and color "red" so you can see it with my dark theme) and I got:

image
which looks correct with what the FontAwesome site says minus-circle is.

I tried with fa5s.user-minus and I get the good icon still:

image

I gather from the style of your window in your screenshot that you're in Windows. (Am I right?) It should work the same way in theory.

I haven't had a chance to try to reproduce the issue on Windows myself yet but I'll try when I'm home on my laptop. (I only have Linux at work.)

Any other details about your environment you'd like to share? It may be helpful to know a few more things: What Windows version are you on, 8 or 10? What PyQt5 version do you have at the moment? On what Python version are you?

@flutefreak7
Copy link
Author

Windows 10
Python 3.6.4 through Anaconda
Qt 5.11.1
PyQt: 5.11.2

I've done some investigating through the qtawesome source and added the following to turn off "Font Merging" that Qt does when it can't find the requested character and falls back to a system font (which is the reason I was seeing unusual glyphs for some characters).

    font = iconic.font(prefix, draw_size)
    font.setStyleStrategy(QFont.NoFontMerging)
    painter.setFont(font)

When I do that I get no icon at all for many of the unicode characters in fontawesome's fonts.

I created a ListWidget of all the solid icons with the above modification. Below is a screenshot of the first 1/3 or so:

image

This lead me to the realization that it is showing icons from the Regular style instead of the Solid style. In the Qt Font database these two fonts have the same family name "Font Awesome 5 Free":
image

This is dealt with by them having different Style Names:
image

...but apparently, despite attempting to get the solid style by name, the resulting QFont is still attempting to look up the characters (the uniode codepoints from the Solid json character map) in the Regular font. A few of the codepoints overlap (like how Address Book is U+F2B9 in both), yielding the incorrect regular version of the desired icon, but for most, Qt goes looking up what it thinks is a similar character in a system font.

I did request the available style names for the font with QFontDatabase and get Regular and Solid:
image

Below is my demo code:

from PyQt5 import QtWidgets, QtGui, QtCore
import qtawesome as qta
from six import unichr
import json

app = QtWidgets.QApplication([])

icon = qta.icon('fa5s.angle-right')

filename = r'C:\Anaconda3\Lib\site-packages\qtawesome\fonts\fontawesome5-solid-webfont-charmap.json'

def hook(obj):
    result = {}
    for key in obj:
        result[key] = unichr(int(obj[key], 16))
    return result

with open(filename, 'r') as f:
    charmap = json.load(f, object_hook=hook)

widget = QtWidgets.QListWidget()

for name, char in charmap.items():
    icon = qta.icon('fa5s.{}'.format(name))
    item = QtWidgets.QListWidgetItem()
    item.setIcon(icon)
    item.setText(name)
    widget.addItem(item)

widget.show()

app.exec_()

@ccordoba12
Copy link
Member

@flutefreak7, thanks for going deep with this. It seems the new FontAwesome 5 support won't work on Windows, sorry.

@flutefreak7
Copy link
Author

There are clearly lots of workarounds to get around this if it's a Windows 10 QFont issue:

  • Rename the font family of the TTF files so that they are all unique - https://github.com/chrissimpkins/fontname.py appears to work fine for this
  • Somehow use the font weight of regular and solid to differentiate them... the original files from fontawesome say the weights are 400 and 900, so perhaps one can get QFont to play along by specifying a weight
  • Dynamically load the font file you need and/or unload the conflicting one - I tried this with my demo of all the icons and it was prohibitively slow of course.
  • Just use the SVG files instead of the TTF files - that'd obviously be a completely different approach that would require different code and wouldn't work for any icon sets that don't provide SVG's

I came up with a solution that works for me that does the TTF font-family rename dynamically within the _instance() function if the user is on Windows and has fontTools installed. I also had to temporarily disable the hash check for the solid file.

This is rough, but perhaps could inspire a cleaner fix or help someone else with the same problem.

Sorry I'm not great at Git, so here's a zip file of my changes:
windows_fix.zip

@flutefreak7
Copy link
Author

flutefreak7 commented Sep 26, 2018

Tried using setWeight to get the correct Style and that didn't work, so I still think renaming the font family in the TTF is the cleanest solution.

Edit: the TTF with the renamed font family could always just be a copy included as a custom font or with a different prefix or something to avoid altering the ttf file from font awesome.

@jules-ch
Copy link

@flutefreak7
I had the same issue on Windows 7 & PyQt 5.10.1 :

It seems setWeight does the trick :

    def font(self, prefix, size):
        """Return a QFont corresponding to the given prefix and size."""
        font = QFont(self.fontname[prefix])
        if prefix[-1] == 's': # solid style
            font.setWeight(900)
        font.setPixelSize(size)
        return font

as a result :

image

@darkvertex
Copy link
Contributor

@jules-ch: Nice! Wanna go ahead and make a PR for this little fix?

@ccordoba12: It seems harmless to me but do you think there are any repercussions to setting the font weight for fa5s?

@jules-ch
Copy link

Tried this at home on Windows 10 & PyQt 5.11.2 and setWeight is not working as @flutefreak7 said.
Don't know how we could have a proper workaround.

@darkvertex
Copy link
Contributor

I think I'd prefer renaming the fonts with that renamer tool. It sounds like the safest choice.

@flutefreak7
Copy link
Author

Just to add to the confusion, according to the docs, Qt uses a 0-99 weight system rather than the system used by... CSS, typography people, and everyone else, so I'm not sure what value is even expected for that to work. I do recall someone on Mac in a Stack Overflow post having issues with setWeight for complex fonts with lots of different weights.

@flutefreak7
Copy link
Author

When I check font.weight() for the 2 fonts I get 50 for both (which should be the default), so at least in my environment that doesn't appear to work as a way to differentiate the two.

@ccordoba12
Copy link
Member

@flutefreak7, @jules-ch, we're welcome to take the solution you think is the best one because fixing this is not a priority for us.

darkvertex added a commit to darkvertex/qtawesome that referenced this issue Sep 28, 2018
…ree (Regular)" and "QtAwesome FontAwesome 5 Free (Solid)" to fix Windows bug spyder-ide#97
@darkvertex
Copy link
Contributor

@flutefreak7 @jules-ch I made a PR using fontname.py to edit the font families, could you give it a try and tell me if it works better for you guys?

@ccordoba12 ccordoba12 added this to the v0.5.1 milestone Sep 28, 2018
darkvertex added a commit to darkvertex/qtawesome that referenced this issue Sep 28, 2018
darkvertex added a commit to darkvertex/qtawesome that referenced this issue Sep 30, 2018
@darkvertex
Copy link
Contributor

Fixed in v0.5.1 - enjoy! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants