How can I get console width?
@Webmaster4o , I think he is asking for something else. Maybe I am wrong, but what I read he just wants something like console.char_width, but of course unless you have a mono spaced font, it's not possible.
The code I put above is very close, but there are some rounding issues with it. I mean to get the screen width in chars given a mono space font
ccc last edited by
I think this is why @omz went with the
measure_string()approach because if you are not using a monospaced font then the number of characters that fits on a line will vary if the string is 'iii' vs. 'www'.
@ccc , sure with any proportional font you have to use a measure string func to calculate the width. You can not even get close without it. Then you have kerning , kerning pairs Etc. kerning, the space between characters, but it gets more complicated by certain character pairs(AE , MY) have a different kerning, but font dependent. Then there is leading on the height. I did a lot with typography in the old days.
Webmaster4o last edited by Webmaster4o
@Phuket2 No, my approach is to do this without changing the font size. I'm trying to discover the font size that is currently active in the console, in order to not have to set it first. I'm trying to create a method that can discover the current console width in characters, without changing the font size.
@Webmaster4o , I think he wants how many chars per line. So you need to calculate one char, but only works for mono space (fixed width) font. I think he is talking terminal speak, like when you knew consoles/terminals would be something like 80x25 or diff depending on resolution. He also says he is new to Python. Anyway, time for him to chime in and say what he really wants. Still good conversation anyway 💋👍
@Webmaster4o , ok you did an edit before I seen it. I just don't think it's practical. If the font is not a fixed width, you have now way to know how many chars will be on any given line.
Why would the console not be a fixed width font? I mean, it is possible of course, but generally console/terminals are fixed width, otherwise it makes things really hard do do anything. We are not talking a generalized textview.
I have not been able to figure out where the text styling info is stored in the OMTextView, I think it is
drawn. It is possible to get the font() size of the console input, which is of type PA2PromptTextField.
@JonB , I am not sure why it would not be a fixed width. But as you mention it's possible to set it to anything. Why can you print bitmap graphics to the console? That was not possible before, but now it is.
Yes, I am also trying to calculate the console width. You are calculating this based on a static font size. It would be more useful and versatile to calculate this based on the current font size, without having to set it first. That is why I am trying to discover what the font size is set at.
Webmaster, I believe the console text input has the same font size as the default console size (ie in settings) though set_font can change what is printed on screen. In that sense, there is no single console width, only the width of a given character(setwidth can change over the line i think). So it would allow you to get the default font, then you would have to manage manual set_font calls. There ts a textStylingAtPosition_InDirection which seems promising, but I have not figured out how not to crash calling it. Also, the textStorage() method of the OMTextView seems promising, but it is not obvious how to get attributes, inly set them.
Balur last edited by
@Phuket2, You are right. Actually, I just want how many chars per line. Maybe a silly approach, but I want my scripts' welcome text underlined with a full line of chars.
consoleWidth = getConsoleWidth() # <= 50 print('DownloadFromWeb') print('Give me an URL, and I will download it for you.') print('='*consoleWidth)
It looks like this in console:
Give me an URL, and I will download it for you.
@Phuket2, I don't want to change console font. Default is good for now. What is the default console font?
measure_string()seems a good approach.
@JonB Yes, I noticed
textStylingAtPosition_InDirection, but also could not get it to work. It appears that OMTextView is a class unique to pythonista that @omz created, I can't find any online resource about it. It seems like a combination of a TextField and a ScrollView. However, it does not have the font() method that a TextField does. Maybe @omz could provide some explanation, another thing that could be tried is comparing all attributes of all views within the console before and after changing the font size.
Balur last edited by Balur
I think I got the missing piece. After a little testing it seems the default console font is Menlo, 14.
import ui def getConsoleWidth(font=('Menlo',14)): screenWidth = ui.get_screen_size().width charWidth = ui.measure_string('.',font=font).width return int(screenWidth / charWidth-1.5)
I'm not sure why subtract by 1.5 exactly, but I think console margin have something to do with it. Tested on my iphone and ipad mini, both orientations.
To check current font:
app=ObjCClass('UIApplication').sharedApplication() d=app.delegate() cv=d.consoleViewController() font=d.consoleViewController().outputFont() print font
Someone else asked about getting the default font, for resetting.
This can be found in defaults.
defaults = ObjCClass('NSUserDefaults').standardUserDefaults() print str(defaults.stringForKey_('OutputFontName')) print defaults.integerForKey_('OutputFontSize')
See defaults.dictionaryRepresentation() for other defaults.
Balur last edited by Balur
@JonB, The current font block of code prints
Nonefor me. The default font one is working and printing
'Menlo-Regular', 12.Which is strange because I not changed my font at all, and it's not 12 but 14.
JonB last edited by JonB
I totally don't understand this, but apparently one needs to trigger an attribute error against the view in order for outputFont to show up... apparently I had done this accidentally while poking around. Indeed the above code didnt work when i restarted, then suddenly worked up again after poking around a bit more. The code below seems to work in a fresh restart. After triggering the error once, all that is needed is to call ouputFont() subsequently.
from objc_util import * app=ObjCClass('UIApplication').sharedApplication() d=app.delegate() cvc=d.consoleViewController() try: cvc.view().thisattributedoesnotexist() except AttributeError: pass font=cvc.outputFont() print font
@Balur , thanks. I will also use your function. I often want to write a full screen divider when debugging. I get lazy though 😱 I set my font in the startup script to Menlo , 22. I have problems seeing smaller. But I tested your function on my ipad pro, and the 1.5 char adjustment works in both orientations.
Balur last edited by
@JonB Strange, but it's do the job. One little problem for me is how to access the values one by one, not this UICTFont object thing?
getConsoleWidth()is still not perfect when I run on ipad when pythonista editor and console are side by side. Because of
ui.get_screen_size().widthreturns the full screen size, not just the console size. I have to subtrack the editor panel width from the full screen size. Or something like that. Any suggestion?
omz last edited by
@JonB I suspect that this has nothing to do with the
AttributeError, but with the fact that you're accessing the
viewproperty while doing the attribute lookup. This has the side effect of loading the view (and typically other setup code) if it isn't loaded already. To be honest, I can't really think of a situation where the console view wouldn't be loaded already, but I can't think of another explanation for this behavior.
@omz indeed, this works for me:
from objc_util import * app=ObjCClass('UIApplication').sharedApplication() d=app.delegate() cvc=d.consoleViewController() cvc.view() font=cvc.outputFont() print font