You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XRANDR中CARD变量类型是什么?Python-Xlib调用set_screen_size报错求助

问题:Python-Xlib调用randr.set_screen_size()报struct.error错误

我正在开发一个用Python-Xlib操控显示器的程序,其他功能正常,但调用randr.set_screen_size()时遇到问题。该函数需要三个参数:窗口变量、两个CARD16类型的宽高参数。查XRANDR文档只看到CARD32、CARD16、CARD8类型的列举,但没说明定义和生成方式。

最初传入整数时报错struct.error: required argument is not an integer,试了字符串、bin生成的二进制也一样。

Edit1:尝试转换为16位无符号整数仍无效

了解到CARD16是16位无符号短整数,参考资料说Python-Xlib用struct处理这类类型,于是尝试提前转成16位无符号整数,代码如下:

import struct
from Xlib import X, display, Xutil
from Xlib.ext import randr

d = display.Display(':0')
screen = 0
info = d.screen(screen)
window = info.root
short16bit = struct.pack("H", int(2000))
randr.set_screen_size(window, short16bit, short16bit)

错误信息:

Traceback (most recent call last):
  File "/home/deishuukaikirpi/XRANDRTesting.py", line 59, in <module>
    randr.set_screen_size(window, short16bit, short16bit)
  File "/home/deishuukaikirpi/.local/lib/python3.9/site-packages/Xlib/ext/randr.py", line 387, in set_screen_size
    return SetScreenSize(
  File "/home/deishuukaikirpi/.local/lib/python3.9/site-packages/Xlib/protocol/rq.py", line 1347, in __init__
    self._binary = self._request.to_binary(*args, **keys)
  File "/home/deishuukaikirpi/.local/lib/python3.9/site-packages/Xlib/protocol/rq.py", line 1069, in to_binary
    static_part = struct.pack(self.static_codes, *pack_items)
struct.error: required argument is not an integer

传入大整数时会报struct.error: ushort format requires 0 <= number <= (0x7fff * 2 + 1),说明确实是要求无符号短整数,但就是报错。

Edit2:确认最初传入的是整数

原始代码直接传整数也报同样错误:

import struct
from Xlib import X, display, Xutil
from Xlib.ext import randr

d = display.Display(':0')
screen = 0
info = d.screen(screen)
window = info.root
randr.set_screen_size(window, 2000, 2000)

甚至用randr.set_screen_size(window,int(2000),int(2000))强制转整数也没用。


解决方案

问题核心是根窗口未订阅RandR事件,Python-Xlib的RandR扩展函数在发送请求前需要窗口已注册接收RandR事件,否则底层协议打包时会抛出看似无关的struct.error。此外,不需要手动用struct.pack处理整数,直接传入0-65535范围内的整数即可。

修正后的代码:

from Xlib import display
from Xlib.ext import randr

# 连接到X服务器
d = display.Display(':0')
screen = d.screen()
root_window = screen.root

# 关键步骤:让根窗口订阅RandR屏幕变更事件
randr.select_input(root_window, randr.RRScreenChangeNotifyMask)

# 直接传入符合CARD16范围的整数
randr.set_screen_size(root_window, 2000, 2000)

# 同步请求,确保命令生效
d.sync()

错误原因解析

  1. 未订阅RandR事件:RandR扩展要求操作窗口必须先订阅相关事件,否则请求打包时会出现参数异常,表现为struct.error而非直接提示未订阅。
  2. 错误使用struct.pack:struct.pack生成的是字节串,而set_screen_size需要的是整数类型,手动打包反而导致类型不匹配,加重错误。

内容的提问来源于stack exchange,提问作者Lazuli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 15:02:01