Closed EpicCodeWizard closed 1 year ago
descriptor.name = "Testing Screen"
descriptor.setName_("Testing Screen")
?
descriptor.setName_("Testing Screen")
?
@dlech That works. How do I translate the dispatch queue line to pyobjc?
descriptor.name = "Testing Screen"
descriptor.setName_("Testing Screen")
?
similar issue i am facing in setting inputFaceObservation.
'VNDetectFaceCaptureQualityRequest' object attribute 'setInputFaceObservations_' is read-only
I am assuming this is a bug and this shouldnt be read-only?
How do I translate the dispatch queue line to pyobjc?
By using the pyobjc-framework-libdispatch
package, you should be able to translate it quite literally (just drop the semicolon).
from libdispatch import dispatch_get_global_queue, DISPATCH_QUEUE_PRIORITY_HIGH
...
I am assuming this is a bug and this shouldnt be read-only?
I don't think so. You should be calling the method, not setting the attribute.
I am assuming this is a bug and this shouldnt be read-only?
I don't think so. You should be calling the method, not setting the attribute.
That's correct, Objective-C properties cannot be used as properties in Python at this time but you have to use getter and setter methods. The problem here is that Python has 1 namespace for attribute and method access, while Objective-C has two (e.g. [anObject name]
vs anObject.name
).
I am assuming this is a bug and this shouldnt be read-only?
I don't think so. You should be calling the method, not setting the attribute.
That's correct, Objective-C properties cannot be used as properties in Python at this time but you have to use getter and setter methods. The problem here is that Python has 1 namespace for attribute and method access, while Objective-C has two (e.g.
[anObject name]
vsanObject.name
).194 has some vague ideas about changing this and the long method names. I'm seriously considering to change over to expose Objective-C properties as properties in Python as well, even if this breaks existing code. That will be a two step process though (add this as an option in PyObjC 10 and enable by default in PyObjC 11).
That would be quite helpful. I enjoy building native apps using Python, but find Objective C to Python quite hard as certain things like setting attributes are confusing.
I'm converting the following code to Python:
id createVirtualDisplay(int width, int height, int ppi, BOOL hiDPI, NSString *name) {
CGVirtualDisplaySettings *settings = [[CGVirtualDisplaySettings alloc] init];
settings.hiDPI = hiDPI;
CGVirtualDisplayDescriptor *descriptor = [[CGVirtualDisplayDescriptor alloc] init];
descriptor.queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
descriptor.name = name;
// See System Preferences > Displays > Color > Open Profile > Apple display native information
descriptor.whitePoint = CGPointMake(0.3125, 0.3291);
descriptor.bluePrimary = CGPointMake(0.1494, 0.0557);
descriptor.greenPrimary = CGPointMake(0.2559, 0.6983);
descriptor.redPrimary = CGPointMake(0.6797, 0.3203);
descriptor.maxPixelsHigh = height;
descriptor.maxPixelsWide = width;
descriptor.sizeInMillimeters = CGSizeMake(25.4 * width / ppi, 25.4 * height / ppi);
descriptor.serialNum = 0;
descriptor.productID = 0;
descriptor.vendorID = 0;
CGVirtualDisplay *display = [[CGVirtualDisplay alloc] initWithDescriptor:descriptor];
if (settings.hiDPI) {
width /= 2;
height /= 2;
}
CGVirtualDisplayMode *mode = [[CGVirtualDisplayMode alloc] initWithWidth:width
height:height
refreshRate:60];
settings.modes = @[mode];
if (![display applySettings:settings])
return nil;
return display;
}
I've gotten so far:
# imports here
def createVirtualDisplay(width: int=1920, height: int=1080, ppi: int=150, hiDPI: bool=True, name: str="Virtual Display") {
settings = CGVirtualDisplaySettings.alloc().init()
settings.setHiDPI_(hiDPI)
descriptor = CGVirtualDisplayDescriptor.alloc().init()
descriptor.setQueue_(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0))
descriptor.setName_(name)
# See System Preferences > Displays > Color > Open Profile > Apple display native information
descriptor.setWhitePoint_(CGPointMake(0.3125, 0.3291))
descriptor.setBluePrimary_(CGPointMake(0.1494, 0.0557))
descriptor.setGreenPrimary_(CGPointMake(0.2559, 0.6983))
descriptor.setRedPrimary_(CGPointMake(0.6797, 0.3203))
descriptor.setMaxPixelsHigh_(height)
descriptor.setMaxPixelsWide_(width)
descriptor.setSizeInMillimeters_(CGSizeMake(25.4 * width / ppi, 25.4 * height / ppi))
descriptor.setSerialNum_(0)
descriptor.setProductID_(0)
descriptor.setVendorID_(0)
# I don't know how to translate the rest
CGVirtualDisplay *display = [[CGVirtualDisplay alloc] initWithDescriptor:descriptor];
if (settings.hiDPI) {
width /= 2;
height /= 2;
}
CGVirtualDisplayMode *mode = [[CGVirtualDisplayMode alloc] initWithWidth:width
height:height
refreshRate:60];
settings.modes = @[mode];
if (![display applySettings:settings])
return nil;
return display;
}
Can you help me translate the rest? I don't understand how to translate the @ symbol or the colon functions.
# CGVirtualDisplay *display = [[CGVirtualDisplay alloc] initWithDescriptor:descriptor];
display = CGVirtualDisplay.alloc().initWithDescriptor_(descriptor)
# if (settings.hiDPI) {
if settings.hiDPI(): # Properties in ObjC must be used with method calls for the accessor
width /= 2
height /= 2
# CGVirtualDisplayMode *mode = [[CGVirtualDisplayMode alloc] initWithWidth:width
# height:height
# refreshRate:60];
mode = CGVirtualDisplayMode.alloc().initWithWidth_height_refreshRate_(width, height, 60)
# settings.modes = @[mode];
settings.setModes_([mode])
# if (![display applySettings:settings])
if display.applySettings_(settings):
return None
return display
In general:
initWithWidth:height:refreshRate:
. The Python proxy uses the same names, but with colons replaced by underscores, e.g. initWithWidth_height_refreshRate_
.@[...]
is a shortcut notation in ObjC for defining an NSArray, use a normal Python list in Python code. In general you can use the normal Python syntax for objects defined using @-notation.I try to use the function - everything goes well, but a virtual display isn't created and None
is returned (meaning that there was some error). Could you spot the bug and fix it?
from Quartz.CoreGraphics import CGVirtualDisplaySettings, CGVirtualDisplayDescriptor, CGVirtualDisplay, CGVirtualDisplayMode, CGPointMake, CGSizeMake
from libdispatch import dispatch_get_global_queue, DISPATCH_QUEUE_PRIORITY_HIGH
def createVirtualDisplay(width: int=1920, height: int=1080, ppi: int=150, hiDPI: bool=True, name: str="Virtual Display"):
settings = CGVirtualDisplaySettings.alloc().init()
settings.setHiDPI_(hiDPI)
descriptor = CGVirtualDisplayDescriptor.alloc().init()
descriptor.setQueue_(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0))
descriptor.setName_(name)
# See System Preferences > Displays > Color > Open Profile > Apple display native information
descriptor.setWhitePoint_(CGPointMake(0.3125, 0.3291))
descriptor.setBluePrimary_(CGPointMake(0.1494, 0.0557))
descriptor.setGreenPrimary_(CGPointMake(0.2559, 0.6983))
descriptor.setRedPrimary_(CGPointMake(0.6797, 0.3203))
descriptor.setMaxPixelsHigh_(height)
descriptor.setMaxPixelsWide_(width)
descriptor.setSizeInMillimeters_(CGSizeMake(25.4 * width / ppi, 25.4 * height / ppi))
descriptor.setSerialNum_(0)
descriptor.setProductID_(0)
descriptor.setVendorID_(0)
display = CGVirtualDisplay.alloc().initWithDescriptor_(descriptor)
if settings.hiDPI():
width /= 2
height /= 2
mode = CGVirtualDisplayMode.alloc().initWithWidth_height_refreshRate_(width, height, 60)
settings.setModes_([mode])
if display.applySettings_(settings):
return None
return display
virtualDisplay = createVirtualDisplay()
print(virtualDisplay)
Nevermind, it works. Thanks for the help!
How did you end up fixing it? I keep running into:
AttributeError: 'NoneType' object has no attribute 'applySettings_'
on this line:
success = self.virtualDisplay.applySettings_(settings)
I tried running the script with sudo but still no luck.
Describe the bug I want to initiate a
CGVirtualDisplayDescriptor
class. I can import it fine. When I do.alloc().init()
, no errors are caused. However, when I try to set an attribute, I receive an error.Platform information Python 3.10.2 python.org,
pyobjc
installed via pip MacOS version 10.15.7To Reproduce I'm trying to mimick this Objective C code in Python:
Expected behavior This should create a virtual display description with that name. Instead, it throws the error:
AttributeError: 'CGVirtualDisplayDescriptor' object attribute 'name' is read-only
.Additional context I'm looking to create a virtual display. I need to provide a virtual display descriptor to create one, which is what I'm doing in this scenario.