كيفية الحصول على عرض نافذة Linux وحدة التحكم في بيثون
سؤال
هل هناك طريقة في بيثون لتحديد عرض وحدة التحكم برمجيا؟ أعني عدد الأحرف التي تناسبها في سطر واحد دون التفاف، وليس عرض البكسل للنافذة.
يحرر
تبحث عن حل يعمل على لينكس
المحلول
import os
rows, columns = os.popen('stty size', 'r').read().split()
يستخدم الأمر "حجم Stty" الذي وفقا ل موضوع على قائمة Python البريدية هو عالمي بشكل معقول على لينكس. إنه يفتح الأمر "STTY SIZE" كملف، "يقرأ" منه، ويستخدم تقسيم سلسلة بسيط لفصل الإحداثيات.
على عكس قيمة OS.ENVIRY ["الأعمدة" ["الأعمدة"] (التي لا يمكنني الوصول إليها على الرغم من استخدام Bash كقذيفة قياسية) ستكون البيانات محدثة أيضا في حين أعتقد أن OS.Environ ["الأعمدة"] ستكون القيمة سارية فقط لوقت إطلاق مترجم الثعبان (لنفترض أن المستخدم تغيير حجم النافذة منذ ذلك الحين).
نصائح أخرى
لست متأكدا لماذا في الوحدة النمطية shutil
, ، لكنه هبط هناك في بيثون 3.3، الاستعلام عن حجم محطة الإخراج:
>>> import shutil
>>> shutil.get_terminal_size((80, 20)) # pass fallback
os.terminal_size(columns=87, lines=23) # returns a named-tuple
التنفيذ المنخفض المستوى هو في وحدة OS.
أصبحت Backport متاحة الآن لبثيون 3.2 وما دون:
استعمال
import console
(width, height) = console.getTerminalSize()
print "Your terminal's width is: %d" % width
تعديل: انا اسف. هذا ليس بيثون قياسي قياسي واحد، إليك مصدر Console.py (لا أعرف أين أنت).
يبدو أن الوحدة النمطية تعمل هكذا: فحدث إذا termcap
متاح، عندما نعم. ويستخدم ذلك؛ إذا لم يكن هناك يتحقق ما إذا كانت المحطة تدعم خاص ioctl
اتصل وهذا لا يعمل أيضا، أيضا، فهو يتحقق من متغيرات البيئة بعض الصادرات القذائف لذلك. هذا من المحتمل أن يعمل على UNIX فقط.
def getTerminalSize():
import os
env = os.environ
def ioctl_GWINSZ(fd):
try:
import fcntl, termios, struct, os
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,
'1234'))
except:
return
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
cr = (env.get('LINES', 25), env.get('COLUMNS', 80))
### Use get(key[, default]) instead of a try/catch
#try:
# cr = (env['LINES'], env['COLUMNS'])
#except:
# cr = (25, 80)
return int(cr[1]), int(cr[0])
الكود أعلاه لم يرجع النتيجة الصحيحة على نظام Linux الخاص بي لأن WinSize-Britch يحتوي على 4 شورت غير موقفي، وليس 2 شرايات موقعة:
def terminal_size():
import fcntl, termios, struct
h, w, hp, wp = struct.unpack('HHHH',
fcntl.ioctl(0, termios.TIOCGWINSZ,
struct.pack('HHHH', 0, 0, 0, 0)))
return w, h
يجب أن يحتوي HP و HP على عرض البكسل والطول، ولكن لا.
لقد بحثت حولها ووجدت حلا للنوافذ في:
http://code.activestate.com/recipes/440694-determine-size-console-window-on-windows/
وحل لينكس هنا.
لذلك هنا نسخة تعمل على حد سواء على Linux و OS X و Windows / Cygwin:
""" getTerminalSize()
- get width and height of console
- works on linux,os x,windows,cygwin(windows)
"""
__all__=['getTerminalSize']
def getTerminalSize():
import platform
current_os = platform.system()
tuple_xy=None
if current_os == 'Windows':
tuple_xy = _getTerminalSize_windows()
if tuple_xy is None:
tuple_xy = _getTerminalSize_tput()
# needed for window's python in cygwin's xterm!
if current_os == 'Linux' or current_os == 'Darwin' or current_os.startswith('CYGWIN'):
tuple_xy = _getTerminalSize_linux()
if tuple_xy is None:
print "default"
tuple_xy = (80, 25) # default value
return tuple_xy
def _getTerminalSize_windows():
res=None
try:
from ctypes import windll, create_string_buffer
# stdin handle is -10
# stdout handle is -11
# stderr handle is -12
h = windll.kernel32.GetStdHandle(-12)
csbi = create_string_buffer(22)
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
except:
return None
if res:
import struct
(bufx, bufy, curx, cury, wattr,
left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
sizex = right - left + 1
sizey = bottom - top + 1
return sizex, sizey
else:
return None
def _getTerminalSize_tput():
# get terminal width
# src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window
try:
import subprocess
proc=subprocess.Popen(["tput", "cols"],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
output=proc.communicate(input=None)
cols=int(output[0])
proc=subprocess.Popen(["tput", "lines"],stdin=subprocess.PIPE,stdout=subprocess.PIPE)
output=proc.communicate(input=None)
rows=int(output[0])
return (cols,rows)
except:
return None
def _getTerminalSize_linux():
def ioctl_GWINSZ(fd):
try:
import fcntl, termios, struct, os
cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ,'1234'))
except:
return None
return cr
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not cr:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
cr = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not cr:
try:
cr = (env['LINES'], env['COLUMNS'])
except:
return None
return int(cr[1]), int(cr[0])
if __name__ == "__main__":
sizex,sizey=getTerminalSize()
print 'width =',sizex,'height =',sizey
ابتداء من Python 3.3 أنها مستقيمة إلى الأمام:https://docs.python.org/3/library/os.html#querying-the-size-of-a-terminal.minal.
>>> import os
>>> ts = os.get_terminal_size()
>>> ts.lines
24
>>> ts.columns
80
انها إما:
import os
columns, rows = os.get_terminal_size(0)
# or
import shutil
columns, rows = shutil.get_terminal_size()
ال shutil
وظيفة هي مجرد التفاف حولها os
واحد يلفت بعض الأخطاء وإعداد الاحتراق، ومع ذلك فإنه يحتوي على تحذير ضخمة - فواصل عندما الأنابيب!, ، وهي صفقة ضخمة جدا.
للحصول على حجم المحطة عند استخدام الأنابيب os.get_terminal_size(0)
في حين أن.
الحجة الأولى 0
هي حجة تشير إلى أن واصف ملف Stdin يجب استخدامه بدلا من Stdout الافتراضي. نريد استخدام Stdin لأن Stdout ينفصل عن نفسه عندما يجري أنابيب ما يرفع في هذه الحالة خطأ ..
لقد حاولت معرفة متى سيكون من المنطقي استخدام Stdout بدلا من حجة Stdin وليس لديك أي فكرة عن سبب ذلك الافتراضي هنا.
يبدو أن هناك بعض المشاكل مع هذا الكود، يوهانس:
getTerminalSize
يحتاج الىimport os
- ما هو
env
ب يشبهos.environ
.
أيضا، لماذا التبديل lines
و cols
قبل العودة؟ إذا TIOCGWINSZ
و stty
كلاهما يقول lines
ومن بعد cols
, ، أقول ترك الأمر بهذه الطريقة. هذا مرتبك لي لمدة 10 دقائق جيدة قبل أن لاحظت التناقض.
سريدهار، لم أحصل على هذا الخطأ عند إخراج الأنابيب. أنا متأكد من أن يتم اكتشافه بشكل صحيح في المحاولة - باستثناء.
باسكال، "HHHH"
لا يعمل على جهازي، ولكن "hh"
هل. كان لدي مشكلة في العثور على وثائق لهذه الوظيفة. يبدو أنه من النظام الأساسي المعتمد.
chochem، مدمجة.
إليك نسختي:
def getTerminalSize():
"""
returns (lines:int, cols:int)
"""
import os, struct
def ioctl_GWINSZ(fd):
import fcntl, termios
return struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234"))
# try stdin, stdout, stderr
for fd in (0, 1, 2):
try:
return ioctl_GWINSZ(fd)
except:
pass
# try os.ctermid()
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
try:
return ioctl_GWINSZ(fd)
finally:
os.close(fd)
except:
pass
# try `stty size`
try:
return tuple(int(x) for x in os.popen("stty size", "r").read().split())
except:
pass
# try environment variables
try:
return tuple(int(os.getenv(var)) for var in ("LINES", "COLUMNS"))
except:
pass
# i give up. return default.
return (25, 80)
ستفشل العديد من تطبيقات Python 2 هنا إذا لم يكن هناك محطة مراقبة عند استدعاء هذا البرنامج النصي. يمكنك التحقق من syss.stdout.isatty () لتحديد ما إذا كان هذا في الواقع محطة، ولكن هذا سيستبعد مجموعة من الحالات، لذلك أعتقد أن الطريقة الأكثر ثباتا لمعرفة حجم المحطة الطرفية هي استخدام حزمة لعنات المدمجة.
import curses
w = curses.initscr()
height, width = w.getmaxyx()
كنت أحاول الحل من هنا الذي يدعو إلى stty size
:
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
ومع ذلك فشل هذا بالنسبة لي لأنني كنت أعمل على برنامج نصي يتوقع إدخال إعادة توجيه على Stdin، و stty
سوف يشكو من أن "ستدين ليس محطة" في هذه الحالة.
كنت قادرا على جعلها تعمل مثل هذا:
with open('/dev/tty') as tty:
height, width = subprocess.check_output(['stty', 'size'], stdin=tty).split()
إجابة @ Reinnual تعمل بشكل جيد، ولكن هناك مشكلة في ذلك: os.popen
تم إهمالها الآن. وبعد ال subprocess
يجب استخدام الوحدة النمطية بدلا من ذلك، إذن إليك إصدار من رمز @ Reannual الذي يستخدم subprocess
وإجابات مباشرة السؤال (عن طريق إعطاء عرض العمود مباشرة ك int
:
import subprocess
columns = int(subprocess.check_output(['stty', 'size']).split()[1])
تم اختباره على نظام التشغيل X 10.9
يحاول "بركات"
كنت أبحث عن نفس الشيء. من السهل جدا استخدامها وتقدم أدوات للتلوين والتصميم وتحديد المواقع في المحطة. ما تحتاجه سهل مثل:
from blessings import Terminal
t = Terminal()
w = t.width
h = t.height
يعمل مثل سحر في لينكس. (لست متأكدا من ماكوسكس والنوافذ)
تحميل وتوثيق هنا
أو يمكنك تثبيته مع PIP:
pip install blessings
إذا كنت تستخدم Python 3.3 أو أعلى، فسوف أوصي المدمج get_terminal_size()
كما أوصت بالفعل. ومع ذلك، إذا كنت عالقا مع إصدار أقدم وأريد طريقة بسيطة وعبر منصة للقيام بذلك، يمكنك استخدامها Asiimatics.. وبعد تدعم هذه الحزمة إصدارات Python مرة أخرى إلى 2.7 وتستخدم خيارات مماثلة لتلك المقترحة أعلاه للحصول على حجم المحطة / وحدة التحكم الحالية.
ببساطة بناء الخاص بك Screen
الطبقة واستخدام dimensions
الممتلكات للحصول على الارتفاع والعرض. وقد ثبت أن هذا يعمل على Linux و OSX و Windows.
أوه - والإفصاح الكامل هنا: أنا المؤلف، لذا لا تتردد في فتح مشكلة جديدة إذا كان لديك أي مشاكل في الحصول على هذا للعمل.
فيما يلي نسخة يجب أن تكون Linux و Solaris متوافق. بناء على المشاركات والكمال من مادشين. وبعد يتطلب وحدة الفرعية.
Sustice Def Soursize (): استيراد Sclex، subprocess، re الناتج = subprocess.check_output (shlex.split (shlex.split ('/ bin / stty -a')) m = re.search ('الصفوف + d + (؟ p d +)؛ الأعمدة D + (؟ p d +)؛ "، الإخراج) إذا م: العودة M.Group (" الصفوف ")، و M.Group (" الأعمدة ") تثير OSERROR (استجابة سيئة:٪ S '٪ (الإخراج))
>>> بشرية () ('40'، '100')