Python программно изменить размер шрифта консоли - PullRequest
0 голосов
/ 14 сентября 2018

Я нашел код ниже, который должен программно изменять размер шрифта консоли.Я на Windows 10.

Однако, какие бы значения я ни настраивал, я не могу получить никакого контроля над размером шрифта, а также по какой-то причине консоль, которая открывается при запуске этого скрипта,очень широкий.

Я понятия не имею, как работает ctypes - все, что я хочу, это изменить размер шрифта консоли изнутри Python.

Любые реальные рабочие решения, пожалуйста?

import ctypes

LF_FACESIZE = 32
STD_OUTPUT_HANDLE = -11

class COORD(ctypes.Structure):
    _fields_ = [("X", ctypes.c_short), ("Y", ctypes.c_short)]

class CONSOLE_FONT_INFOEX(ctypes.Structure):
    _fields_ = [("cbSize", ctypes.c_ulong),
                ("nFont", ctypes.c_ulong),
                ("dwFontSize", COORD),
                ("FontFamily", ctypes.c_uint),
                ("FontWeight", ctypes.c_uint),
                ("FaceName", ctypes.c_wchar * LF_FACESIZE)]

font = CONSOLE_FONT_INFOEX()
font.cbSize = ctypes.sizeof(CONSOLE_FONT_INFOEX)
font.nFont = 12
font.dwFontSize.X = 11
font.dwFontSize.Y = 18
font.FontFamily = 54
font.FontWeight = 400
font.FaceName = "Lucida Console"

handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
ctypes.windll.kernel32.SetCurrentConsoleFontEx(
        handle, ctypes.c_long(False), ctypes.pointer(font))


print("Foo")

Ответы [ 2 ]

0 голосов
/ 15 сентября 2018

Я хочу начать с указания либо:

Страница ctypes (также указанная в приведенных выше URL s): [Python 3.Docs]: ctypes - библиотека сторонних функций для Python

Я изменил ваш код "бит".

code.py :

#!/usr/bin/env python

import sys
from ctypes import POINTER, WinDLL, Structure, sizeof, byref
from ctypes.wintypes import BOOL, SHORT, WCHAR, UINT, ULONG, DWORD, HANDLE


LF_FACESIZE = 32
STD_OUTPUT_HANDLE = -11


class COORD(Structure):
    _fields_ = [
        ("X", SHORT),
        ("Y", SHORT),
    ]


class CONSOLE_FONT_INFOEX(Structure):
    _fields_ = [
        ("cbSize", ULONG),
        ("nFont", DWORD),
        ("dwFontSize", COORD),
        ("FontFamily", UINT),
        ("FontWeight", UINT),
        ("FaceName", WCHAR * LF_FACESIZE)
    ]


kernel32_dll = WinDLL("kernel32.dll")

get_last_error_func = kernel32_dll.GetLastError
get_last_error_func.argtypes = []
get_last_error_func.restype = DWORD

get_std_handle_func = kernel32_dll.GetStdHandle
get_std_handle_func.argtypes = [DWORD]
get_std_handle_func.restype = HANDLE

get_current_console_font_ex_func = kernel32_dll.GetCurrentConsoleFontEx
get_current_console_font_ex_func.argtypes = [HANDLE, BOOL, POINTER(CONSOLE_FONT_INFOEX)]
get_current_console_font_ex_func.restype = BOOL

set_current_console_font_ex_func = kernel32_dll.SetCurrentConsoleFontEx
set_current_console_font_ex_func.argtypes = [HANDLE, BOOL, POINTER(CONSOLE_FONT_INFOEX)]
set_current_console_font_ex_func.restype = BOOL


def main():
    # Get stdout handle
    stdout = get_std_handle_func(STD_OUTPUT_HANDLE)
    if not stdout:
        print("{:s} error: {:d}".format(get_std_handle_func.__name__, get_last_error_func()))
        return
    # Get current font characteristics
    font = CONSOLE_FONT_INFOEX()
    font.cbSize = sizeof(CONSOLE_FONT_INFOEX)
    res = get_current_console_font_ex_func(stdout, False, byref(font))
    if not res:
        print("{:s} error: {:d}".format(get_current_console_font_ex_func.__name__, get_last_error_func()))
        return
    # Display font information
    print("Console information for {:}".format(font))
    for field_name, _ in font._fields_:
        field_data = getattr(font, field_name)
        if field_name == "dwFontSize":
            print("    {:s}: {{X: {:d}, Y: {:d}}}".format(field_name, field_data.X, field_data.Y))
        else:
            print("    {:s}: {:}".format(field_name, field_data))
    while 1:
        try:
            height = int(input("\nEnter font height (invalid to exit): "))
        except:
            break
        # Alter font height
        font.dwFontSize.X = 10  # Changing X has no effect (at least on my machine)
        font.dwFontSize.Y = height
        # Apply changes
        res = set_current_console_font_ex_func(stdout, False, byref(font))
        if not res:
            print("{:s} error: {:d}".format(set_current_console_font_ex_func.__name__, get_last_error_func()))
            return
        print("OMG! The window changed :)")
        # Get current font characteristics again and display font size
        res = get_current_console_font_ex_func(stdout, False, byref(font))
        if not res:
            print("{:s} error: {:d}".format(get_current_console_font_ex_func.__name__, get_last_error_func()))
            return
        print("\nNew sizes    X: {:d}, Y: {:d}".format(font.dwFontSize.X, font.dwFontSize.Y))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

Примечания

  • ctypes обеспечивает низкоуровневый доступ, аналогичный C (только синтаксис: Python )
  • Код использует [MS.Docs]: функция SetConsoleTextAttribute
  • Константы ctypes.wintypes (которые ссылаются на стандартные типы ctypes ) используются (чтобы придать коду Win подобный аромат)
  • Это очень (почти болезненно) долго (также потому что я добавил правильную обработку ошибок)
  • Альтернативой, как предлагается в одном из ответов [SO]: изменить шрифт консоли в Windows (откуда вы скопировали код), будет установка 3 rd -party модуль (например, [GitHub]: mhammond / pywin32 - расширения Python для Windows (pywin32) , который является оболочкой Python над WINAPI с), который будет для написания кода требуется меньше кода, поскольку мостовое соединение между Python и C уже будет реализовано, и, вероятно, вышеуказанная функциональность может быть реализована всего за несколько строк
  • Как я прокомментировал в коде, настройка COORD.X, похоже, игнорируется. Но он автоматически устанавливается при установке COORD.Y (на значение, близкое к COORD.Y // 2 - возможно, для сохранения соотношения сторон). На моей машине ( Win 10 x64 ) значением по умолчанию является 16 . Возможно, вы захотите установить его обратно в конце, чтобы не оставлять консоль в «сложном» состоянии (очевидно, Win корректирует cmd размер окна, чтобы быть (вроде) в синхронизировать с размером шрифта):

    PrintScreen

0 голосов
/ 14 сентября 2018

Это не проблема чисто Python, но охватывает Windows API.

Посмотрите документацию CONSOLE_FONT_INFOEX структуры. На нем есть элемент COORD для ширины и высоты каждого символа.

Чтобы изменить размер шрифта консоли, вы можете присвоить этим атрибутам правильное значение:

font.dwFontSize.X = 11
font.dwFontSize.Y = 18

Ссылка: Изменить шрифт консоли в Windows

...