XRANDR 中的 CARD 变量类型是什么?

问题描述 投票:0回答:2

编辑2: 澄清一下,整数是我最初输入程序的内容。在我开始测试任何东西之前,我的原始代码是这样的:

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)

它给了我相同的 struct.error: required argument is not an integer。我也做了

randr.set_screen_size(window,int(2000),int(2000))
,只是为了确保我输入的是整数,并且也返回了相同的 struct.error。

编辑1: 据我了解,CARD 似乎是无符号整数类型,而 CARD16 是无符号 16 位短整型。根据 Roland Smith 的回答,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: required argument is not an integer
错误。有趣的是,如果我将足够大的整数放入宽度或高度中,我会收到错误
struct.error: ushort format requires 0 <= number <= (0x7fff * 2 + 1)
,这似乎暗示这是一个无符号短整型。

原文: 我正在开发一个程序,可以让我通过 Python-Xlib 操作显示。我让一切正常工作并弄清楚了一切,直到我点击 randr.set_screen_size()。它有三个必要的参数 - self,它接受一个窗口变量,以及 length 和 width,它们分别接受 CARD16 变量。我找到的我一直在使用的 XRANDR 的文档,在这里找到,概述了 CARD32、CARD16 和 CARD8 作为变量类型,但没有解释它们是什么,也没有解释如何生成它们。

我以为它们本来只是特殊的整数变量,因此输入了整数。我收到错误“struct.error:所需参数不是整数。”然后我尝试通过 bin 函数输入字符串和二进制,它们都返回与我输入整数时相同的错误。

python python-3.x xlib xrandr
2个回答
2
投票

看着

xrandr.py
,我们看到

from Xlib.protocol import rq

class SetScreenSize(rq.Request):
    _request = rq.Struct(
        rq.Card8('opcode'),
        rq.Opcode(7),
        rq.RequestLength(),
        rq.Window('window'),
        rq.Card16('width'),
        rq.Card16('height'),
        rq.Card32('width_in_millimeters'),
        rq.Card32('height_in_millimeters'),
        )

def set_screen_size(self, width, height, width_in_millimeters=None, height_in_millimeters=None):
    return SetScreenSize(
        display=self.display,
        opcode=self.display.get_extension_major(extname),
        window=self,
        width=width,
        height=height,
        width_in_millimeters=width_in_millimeters,
        height_in_millimeters=height_in_millimeters,
        )

看着

protocol/rq.py
,我们看到:

class Card16(ValueField):
    structcode = 'H'
    structvalues = 1

class Card32(ValueField):
    structcode = 'L'
    structvalues = 1

所以这些卡似乎使用了标准库的

struct
模块。

查看标准库的

struct
模块的文档,
H
是无符号短整型,
L
是无符号长整型。

仔细查看错误消息的内容;

struct.error:所需参数不是整数。

这意味着所讨论的参数无法转换为整数。 您可能使用浮点数或字符串吗?因为 struct 模块不会转换这些;

In [1]: import struct

In [2]: struct.pack("H", 32)
Out[2]: b' \x00'

In [3]: struct.pack("L", 327)
Out[3]: b'G\x01\x00\x00\x00\x00\x00\x00'

In [4]: struct.pack("H", 32.0)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
Cell In[4], line 1
----> 1 struct.pack("H", 32.0)

error: required argument is not an integer

In [5]: struct.pack("H", "32")
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
Cell In[5], line 1
----> 1 struct.pack("H", "32")

error: required argument is not an integer

请注意这如何导致您看到的确切错误消息。

如果提供的值是整数但超出范围,您将得到不同的错误;

---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
Cell In[6], line 1
----> 1 struct.pack("H", 2**16+1)

error: ushort format requires 0 <= number <= 0xffff

尝试将值显式转换为整数,然后再将其传递给

CardXX
类。适用于浮点数和字符串:

In [7]: struct.pack("H", int(32.0))
Out[7]: b' \x00'

In [8]: struct.pack("H", int("32"))
Out[8]: b' \x00'

0
投票

好的,我发现问题了。 set_screen_size实际上有5个参数:self,它接受一个窗口对象,width和height分别接受CARD16对象,最后width_in_mms和height_in_mms接受CARD32对象。我认为 width_in_mms 或 height_in_mms 并不重要,因为它们在 Xlib 代码中自动设置为 None,但显然它确实很重要。这仍然没有让程序正常工作,因为现在它没有返回错误,而是没有执行其应该执行的操作,但我将为此开始一个新问题。

所以回答标题问题: CARD 是基数号码的缩写。基数是非负整数。 XRANDR 中的 CARD8、CARD16 和 CARD32 分别是无符号字符、无符号短整型和无符号长整型。 Python 本身并不支持这些,但可以使用 struct 库重新创建它们。

© www.soinside.com 2019 - 2024. All rights reserved.