1
0
Fork 0
mirror of https://github.com/kbumsik/VirtScreen.git synced 2025-02-12 11:21:53 +00:00

Conformance to PEP 8

This commit is contained in:
Bumsik Kim 2018-05-16 17:37:24 -04:00
parent 6ccdd556f2
commit 9001fee975
No known key found for this signature in database
GPG key ID: E31041C8EC5B01C6

View file

@ -6,20 +6,20 @@ from enum import Enum
from typing import List, Dict from typing import List, Dict
from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QObject, QUrl, Qt, pyqtProperty, pyqtSlot, pyqtSignal, Q_ENUMS from PyQt5.QtCore import QObject, QUrl, Qt, pyqtProperty, pyqtSlot, pyqtSignal, Q_ENUMS
from PyQt5.QtGui import QIcon, QCursor from PyQt5.QtGui import QIcon, QCursor
from PyQt5.QtQml import qmlRegisterType, QQmlApplicationEngine, QQmlListProperty from PyQt5.QtQml import qmlRegisterType, QQmlApplicationEngine, QQmlListProperty
from twisted.internet import protocol, error from twisted.internet import protocol, error
from netifaces import interfaces, ifaddresses, AF_INET from netifaces import interfaces, ifaddresses, AF_INET
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# file path definitions # file path definitions
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
# Sanitize environment variables # Sanitize environment variables
# https://wiki.sei.cmu.edu/confluence/display/c/ENV03-C.+Sanitize+the+environment+when+invoking+external+programs # https://wiki.sei.cmu.edu/confluence/display/c/ENV03-C.+Sanitize+the+environment+when+invoking+external+programs
del os.environ['HOME'] # Delete $HOME env for security reason. This will make del os.environ['HOME'] # Delete $HOME env for security reason. This will make
# Path.home() to look up in the password directory (pwd module) # Path.home() to look up in the password directory (pwd module)
os.environ['PATH'] = os.confstr("CS_PATH") # Sanitize $PATH os.environ['PATH'] = os.confstr("CS_PATH") # Sanitize $PATH
HOME_PATH = str(Path.home()) HOME_PATH = str(Path.home())
@ -35,25 +35,27 @@ ICON_PATH = PROGRAM_PATH + "/icon/icon.png"
ICON_TABLET_OFF_PATH = PROGRAM_PATH + "/icon/icon_tablet_off.png" ICON_TABLET_OFF_PATH = PROGRAM_PATH + "/icon/icon_tablet_off.png"
ICON_TABLET_ON_PATH = PROGRAM_PATH + "/icon/icon_tablet_on.png" ICON_TABLET_ON_PATH = PROGRAM_PATH + "/icon/icon_tablet_on.png"
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
# Subprocess wrapper # Subprocess wrapper
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
class SubprocessWrapper: class SubprocessWrapper:
def __init__(self): def __init__(self):
pass pass
def check_output(self, arg) -> None: def check_output(self, arg) -> None:
return subprocess.check_output(arg.split(), stderr=subprocess.STDOUT).decode('utf-8') return subprocess.check_output(arg.split(), stderr=subprocess.STDOUT).decode('utf-8')
def run(self, arg: str, input: str = None, check=False) -> str: def run(self, arg: str, input: str = None, check=False) -> str:
if input: if input:
input = input.encode('utf-8') input = input.encode('utf-8')
return subprocess.run(arg.split(), input=input, stdout=subprocess.PIPE, return subprocess.run(arg.split(), input=input, stdout=subprocess.PIPE,
check=check, stderr=subprocess.STDOUT).stdout.decode('utf-8') check=check, stderr=subprocess.STDOUT).stdout.decode('utf-8')
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
# Twisted class # Twisted class
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
class ProcessProtocol(protocol.ProcessProtocol): class ProcessProtocol(protocol.ProcessProtocol):
def __init__(self, onConnected, onOutReceived, onErrRecevied, onProcessEnded, logfile=None): def __init__(self, onConnected, onOutReceived, onErrRecevied, onProcessEnded, logfile=None):
self.onConnected = onConnected self.onConnected = onConnected
@ -61,7 +63,7 @@ class ProcessProtocol(protocol.ProcessProtocol):
self.onErrRecevied = onErrRecevied self.onErrRecevied = onErrRecevied
self.onProcessEnded = onProcessEnded self.onProcessEnded = onProcessEnded
self.logfile = logfile self.logfile = logfile
def run(self, arg: str): def run(self, arg: str):
"""Spawn a process """Spawn a process
@ -80,7 +82,7 @@ class ProcessProtocol(protocol.ProcessProtocol):
def connectionMade(self): def connectionMade(self):
print("connectionMade!") print("connectionMade!")
self.onConnected() self.onConnected()
self.transport.closeStdin() # No more input self.transport.closeStdin() # No more input
def outReceived(self, data): def outReceived(self, data):
# print("outReceived! with %d bytes!" % len(data)) # print("outReceived! with %d bytes!" % len(data))
@ -125,12 +127,14 @@ class ProcessProtocol(protocol.ProcessProtocol):
print("quitting") print("quitting")
self.onProcessEnded(exitCode) self.onProcessEnded(exitCode)
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
# Display properties # Display properties
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
class Display(object): class Display(object):
__slots__ = ['name', 'primary', 'connected', 'active', 'width', 'height', 'x_offset', 'y_offset'] __slots__ = ['name', 'primary', 'connected', 'active', 'width', 'height', 'x_offset', 'y_offset']
def __init__(self, parent=None):
def __init__(self):
self.name: str = None self.name: str = None
self.primary: bool = False self.primary: bool = False
self.connected: bool = False self.connected: bool = False
@ -154,9 +158,8 @@ class Display(object):
ret += f" not active {self.width}x{self.height}" ret += f" not active {self.width}x{self.height}"
return ret return ret
class DisplayProperty(QObject):
_display: Display
class DisplayProperty(QObject):
def __init__(self, display: Display, parent=None): def __init__(self, display: Display, parent=None):
super(DisplayProperty, self).__init__(parent) super(DisplayProperty, self).__init__(parent)
self._display = display self._display = display
@ -168,6 +171,7 @@ class DisplayProperty(QObject):
@pyqtProperty(str, constant=True) @pyqtProperty(str, constant=True)
def name(self): def name(self):
return self._display.name return self._display.name
@name.setter @name.setter
def name(self, name): def name(self, name):
self._display.name = name self._display.name = name
@ -175,6 +179,7 @@ class DisplayProperty(QObject):
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def primary(self): def primary(self):
return self._display.primary return self._display.primary
@primary.setter @primary.setter
def primary(self, primary): def primary(self, primary):
self._display.primary = primary self._display.primary = primary
@ -182,6 +187,7 @@ class DisplayProperty(QObject):
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def connected(self): def connected(self):
return self._display.connected return self._display.connected
@connected.setter @connected.setter
def connected(self, connected): def connected(self, connected):
self._display.connected = connected self._display.connected = connected
@ -189,6 +195,7 @@ class DisplayProperty(QObject):
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def active(self): def active(self):
return self._display.active return self._display.active
@active.setter @active.setter
def active(self, active): def active(self, active):
self._display.active = active self._display.active = active
@ -196,6 +203,7 @@ class DisplayProperty(QObject):
@pyqtProperty(int, constant=True) @pyqtProperty(int, constant=True)
def width(self): def width(self):
return self._display.width return self._display.width
@width.setter @width.setter
def width(self, width): def width(self, width):
self._display.width = width self._display.width = width
@ -203,6 +211,7 @@ class DisplayProperty(QObject):
@pyqtProperty(int, constant=True) @pyqtProperty(int, constant=True)
def height(self): def height(self):
return self._display.height return self._display.height
@height.setter @height.setter
def height(self, height): def height(self, height):
self._display.height = height self._display.height = height
@ -210,6 +219,7 @@ class DisplayProperty(QObject):
@pyqtProperty(int, constant=True) @pyqtProperty(int, constant=True)
def x_offset(self): def x_offset(self):
return self._display.x_offset return self._display.x_offset
@x_offset.setter @x_offset.setter
def x_offset(self, x_offset): def x_offset(self, x_offset):
self._display.x_offset = x_offset self._display.x_offset = x_offset
@ -217,13 +227,15 @@ class DisplayProperty(QObject):
@pyqtProperty(int, constant=True) @pyqtProperty(int, constant=True)
def y_offset(self): def y_offset(self):
return self._display.y_offset return self._display.y_offset
@y_offset.setter @y_offset.setter
def y_offset(self, y_offset): def y_offset(self, y_offset):
self._display.y_offset = y_offset self._display.y_offset = y_offset
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
# Screen adjustment class # Screen adjustment class
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
class XRandR(SubprocessWrapper): class XRandR(SubprocessWrapper):
DEFAULT_VIRT_SCREEN = "VIRTUAL1" DEFAULT_VIRT_SCREEN = "VIRTUAL1"
VIRT_SCREEN_SUFFIX = "_virt" VIRT_SCREEN_SUFFIX = "_virt"
@ -238,7 +250,7 @@ class XRandR(SubprocessWrapper):
self.primary_idx: int = None self.primary_idx: int = None
# Primary display # Primary display
self._update_screens() self._update_screens()
def _update_screens(self) -> None: def _update_screens(self) -> None:
output = self.run("xrandr") output = self.run("xrandr")
self.primary = None self.primary = None
@ -246,7 +258,7 @@ class XRandR(SubprocessWrapper):
self.screens = [] self.screens = []
self.primary_idx = None self.primary_idx = None
pattern = re.compile(r"^(\S*)\s+(connected|disconnected)\s+((primary)\s+)?" pattern = re.compile(r"^(\S*)\s+(connected|disconnected)\s+((primary)\s+)?"
r"((\d+)x(\d+)\+(\d+)\+(\d+)\s+)?.*$", re.M) r"((\d+)x(\d+)\+(\d+)\+(\d+)\s+)?.*$", re.M)
for idx, match in enumerate(pattern.finditer(output)): for idx, match in enumerate(pattern.finditer(output)):
screen = Display() screen = Display()
screen.name = match.group(1) screen.name = match.group(1)
@ -268,7 +280,7 @@ class XRandR(SubprocessWrapper):
for s in self.screens: for s in self.screens:
print("\t", s) print("\t", s)
if self.virt_idx == self.primary_idx: if self.virt_idx == self.primary_idx:
raise RuntimeError("VIrtual screen must be selected other than the primary screen") raise RuntimeError("Virtual screen must be selected other than the primary screen")
if self.virt_idx is None: if self.virt_idx is None:
for idx, screen in enumerate(self.screens): for idx, screen in enumerate(self.screens):
if not screen.connected and not screen.active: if not screen.connected and not screen.active:
@ -318,7 +330,7 @@ class XRandR(SubprocessWrapper):
def get_virtual_screen(self) -> Display: def get_virtual_screen(self) -> Display:
self._update_screens() self._update_screens()
return self.virt return self.virt
def create_virtual_screen(self, width, height, portrait=False, hidpi=False) -> None: def create_virtual_screen(self, width, height, portrait=False, hidpi=False) -> None:
print("creating: ", self.virt) print("creating: ", self.virt)
self._add_screen_mode(width, height, portrait, hidpi) self._add_screen_mode(width, height, portrait, hidpi)
@ -338,11 +350,13 @@ class XRandR(SubprocessWrapper):
atexit.unregister(self.delete_virtual_screen) atexit.unregister(self.delete_virtual_screen)
self._update_screens() self._update_screens()
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
# QML Backend class # QML Backend class
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
class Backend(QObject): class Backend(QObject):
""" Backend class for QML frontend """ """ Backend class for QML frontend """
class VNCState: class VNCState:
""" Enum to indicate a state of the VNC server """ """ Enum to indicate a state of the VNC server """
OFF = 0 OFF = 0
@ -373,7 +387,7 @@ class Backend(QObject):
# Primary screen and mouse posistion # Primary screen and mouse posistion
self._primaryProp: DisplayProperty self._primaryProp: DisplayProperty
self.vncServer: ProcessProtocol self.vncServer: ProcessProtocol
# Qt properties # Qt properties
@pyqtProperty(str, constant=True) @pyqtProperty(str, constant=True)
def settings(self): def settings(self):
@ -383,14 +397,16 @@ class Backend(QObject):
except FileNotFoundError: except FileNotFoundError:
with open(DEFAULT_CONFIG_PATH, "r") as f: with open(DEFAULT_CONFIG_PATH, "r") as f:
return f.read() return f.read()
@settings.setter @settings.setter
def settings(self, json_str): def settings(self, json_str):
with open(CONFIG_PATH, "w") as f: with open(CONFIG_PATH, "w") as f:
f.write(json_str) f.write(json_str)
@pyqtProperty(bool, notify=onVirtScreenCreatedChanged) @pyqtProperty(bool, notify=onVirtScreenCreatedChanged)
def virtScreenCreated(self): def virtScreenCreated(self):
return self._virtScreenCreated return self._virtScreenCreated
@virtScreenCreated.setter @virtScreenCreated.setter
def virtScreenCreated(self, value): def virtScreenCreated(self, value):
self._virtScreenCreated = value self._virtScreenCreated = value
@ -403,6 +419,7 @@ class Backend(QObject):
@pyqtProperty(int, notify=onVirtScreenIndexChanged) @pyqtProperty(int, notify=onVirtScreenIndexChanged)
def virtScreenIndex(self): def virtScreenIndex(self):
return self._virtScreenIndex return self._virtScreenIndex
@virtScreenIndex.setter @virtScreenIndex.setter
def virtScreenIndex(self, virtScreenIndex): def virtScreenIndex(self, virtScreenIndex):
print("Changing virt to ", virtScreenIndex) print("Changing virt to ", virtScreenIndex)
@ -418,6 +435,7 @@ class Backend(QObject):
if self._vncUsePassword: if self._vncUsePassword:
self.vncUsePassword = False self.vncUsePassword = False
return self._vncUsePassword return self._vncUsePassword
@vncUsePassword.setter @vncUsePassword.setter
def vncUsePassword(self, use): def vncUsePassword(self, use):
self._vncUsePassword = use self._vncUsePassword = use
@ -426,6 +444,7 @@ class Backend(QObject):
@pyqtProperty(VNCState, notify=onVncStateChanged) @pyqtProperty(VNCState, notify=onVncStateChanged)
def vncState(self): def vncState(self):
return self._vncState return self._vncState
@vncState.setter @vncState.setter
def vncState(self, state): def vncState(self, state):
self._vncState = state self._vncState = state
@ -442,7 +461,7 @@ class Backend(QObject):
for link in addresses: for link in addresses:
if link is not None: if link is not None:
yield link['addr'] yield link['addr']
@pyqtProperty(DisplayProperty) @pyqtProperty(DisplayProperty)
def primary(self): def primary(self):
self._primaryProp = DisplayProperty(self.xrandr.get_primary_screen()) self._primaryProp = DisplayProperty(self.xrandr.get_primary_screen())
@ -457,7 +476,7 @@ class Backend(QObject):
def cursor_y(self): def cursor_y(self):
cursor = QCursor().pos() cursor = QCursor().pos()
return cursor.y() return cursor.y()
# Qt Slots # Qt Slots
@pyqtSlot(int, int, bool, bool) @pyqtSlot(int, int, bool, bool)
def createVirtScreen(self, width, height, portrait, hidpi): def createVirtScreen(self, width, height, portrait, hidpi):
@ -468,7 +487,7 @@ class Backend(QObject):
self.onError.emit(str(e.cmd) + '\n' + e.stdout.decode('utf-8')) self.onError.emit(str(e.cmd) + '\n' + e.stdout.decode('utf-8'))
return return
self.virtScreenCreated = True self.virtScreenCreated = True
@pyqtSlot() @pyqtSlot()
def deleteVirtScreen(self): def deleteVirtScreen(self):
print("Deleting the Virtual Screen...") print("Deleting the Virtual Screen...")
@ -478,11 +497,11 @@ class Backend(QObject):
return return
self.xrandr.delete_virtual_screen() self.xrandr.delete_virtual_screen()
self.virtScreenCreated = False self.virtScreenCreated = False
@pyqtSlot(str) @pyqtSlot(str)
def createVNCPassword(self, password): def createVNCPassword(self, password):
if password: if password:
password += '\n' + password + '\n\n' # verify + confirm password += '\n' + password + '\n\n' # verify + confirm
p = SubprocessWrapper() p = SubprocessWrapper()
try: try:
p.run(f"x11vnc -storepasswd {X11VNC_PASSWORD_PATH}", input=password, check=True) p.run(f"x11vnc -storepasswd {X11VNC_PASSWORD_PATH}", input=password, check=True)
@ -513,10 +532,12 @@ class Backend(QObject):
# regex used in callbacks # regex used in callbacks
patter_connected = re.compile(r"^.*Got connection from client.*$", re.M) patter_connected = re.compile(r"^.*Got connection from client.*$", re.M)
patter_disconnected = re.compile(r"^.*client_count: 0*$", re.M) patter_disconnected = re.compile(r"^.*client_count: 0*$", re.M)
# define callbacks # define callbacks
def _onConnected(): def _onConnected():
print("VNC started.") print("VNC started.")
self.vncState = self.VNCState.WAITING self.vncState = self.VNCState.WAITING
def _onReceived(data): def _onReceived(data):
data = data.decode("utf-8") data = data.decode("utf-8")
if (self._vncState is not self.VNCState.CONNECTED) and patter_connected.search(data): if (self._vncState is not self.VNCState.CONNECTED) and patter_connected.search(data):
@ -525,15 +546,17 @@ class Backend(QObject):
if (self._vncState is self.VNCState.CONNECTED) and patter_disconnected.search(data): if (self._vncState is self.VNCState.CONNECTED) and patter_disconnected.search(data):
print("VNC disconnected.") print("VNC disconnected.")
self.vncState = self.VNCState.WAITING self.vncState = self.VNCState.WAITING
def _onEnded(exitCode): def _onEnded(exitCode):
if exitCode is not 0: if exitCode is not 0:
self.vncState = self.VNCState.ERROR self.vncState = self.VNCState.ERROR
self.onError.emit('X11VNC: Error occurred.\nDouble check if the port is already used.') self.onError.emit('X11VNC: Error occurred.\nDouble check if the port is already used.')
self.vncState = self.VNCState.OFF # TODO: better handling error state self.vncState = self.VNCState.OFF # TODO: better handling error state
else: else:
self.vncState = self.VNCState.OFF self.vncState = self.VNCState.OFF
print("VNC Exited.") print("VNC Exited.")
atexit.unregister(self.stopVNC) atexit.unregister(self.stopVNC)
logfile = open(X11VNC_LOG_PATH, "wb") logfile = open(X11VNC_LOG_PATH, "wb")
self.vncServer = ProcessProtocol(_onConnected, _onReceived, _onReceived, _onEnded, logfile) self.vncServer = ProcessProtocol(_onConnected, _onReceived, _onReceived, _onEnded, logfile)
virt = self.xrandr.get_virtual_screen() virt = self.xrandr.get_virtual_screen()
@ -550,13 +573,16 @@ class Backend(QObject):
# define callbacks # define callbacks
def _onConnected(): def _onConnected():
print("External Display Setting opened.") print("External Display Setting opened.")
def _onReceived(data): def _onReceived(data):
pass pass
def _onEnded(exitCode): def _onEnded(exitCode):
print("External Display Setting closed.") print("External Display Setting closed.")
self.onDisplaySettingClosed.emit() self.onDisplaySettingClosed.emit()
if exitCode is not 0: if exitCode is not 0:
self.onError.emit(f'Error opening "{running_program}".') self.onError.emit(f'Error opening "{running_program}".')
program_list = ["gnome-control-center display", "arandr"] program_list = ["gnome-control-center display", "arandr"]
program = ProcessProtocol(_onConnected, _onReceived, _onReceived, _onEnded, None) program = ProcessProtocol(_onConnected, _onReceived, _onReceived, _onEnded, None)
running_program = '' running_program = ''
@ -567,18 +593,18 @@ class Backend(QObject):
program.run(arg) program.run(arg)
return return
self.onError.emit('Failed to find a display settings program.\n' self.onError.emit('Failed to find a display settings program.\n'
'Please install ARandR package.\n' 'Please install ARandR package.\n'
'(e.g. sudo apt-get install arandr)\n' '(e.g. sudo apt-get install arandr)\n'
'Please issue a feature request\n' 'Please issue a feature request\n'
'if you wish to add a display settings\n' 'if you wish to add a display settings\n'
'program for your Desktop Environment.') 'program for your Desktop Environment.')
@pyqtSlot() @pyqtSlot()
def stopVNC(self, force=False): def stopVNC(self, force=False):
if force: if force:
# Usually called from atexit(). # Usually called from atexit().
self.vncServer.kill() self.vncServer.kill()
time.sleep(2) # Make sure X11VNC shutdown before execute next atexit. time.sleep(2) # Make sure X11VNC shutdown before execute next atexit().
if self._vncState in (self.VNCState.WAITING, self.VNCState.CONNECTED): if self._vncState in (self.VNCState.WAITING, self.VNCState.CONNECTED):
self.vncServer.kill() self.vncServer.kill()
else: else:
@ -590,12 +616,13 @@ class Backend(QObject):
@pyqtSlot() @pyqtSlot()
def quitProgram(self): def quitProgram(self):
self.blockSignals(True) # This will prevent invoking auto-restart or etc. self.blockSignals(True) # This will prevent invoking auto-restart or etc.
QApplication.instance().quit() QApplication.instance().quit()
#-------------------------------------------------------------------------------
# -------------------------------------------------------------------------------
# Main Code # Main Code
#------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
if __name__ == '__main__': if __name__ == '__main__':
QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv) app = QApplication(sys.argv)
@ -604,33 +631,34 @@ if __name__ == '__main__':
if not QSystemTrayIcon.isSystemTrayAvailable(): if not QSystemTrayIcon.isSystemTrayAvailable():
QMessageBox.critical(None, "VirtScreen", QMessageBox.critical(None, "VirtScreen",
"Cannot detect system tray on this system.") "Cannot detect system tray on this system.")
sys.exit(1) sys.exit(1)
if os.environ['XDG_SESSION_TYPE'] == 'wayland': if os.environ['XDG_SESSION_TYPE'] == 'wayland':
QMessageBox.critical(None, "VirtScreen", QMessageBox.critical(None, "VirtScreen",
"Currently Wayland is not supported") "Currently Wayland is not supported")
sys.exit(1) sys.exit(1)
if not HOME_PATH: if not HOME_PATH:
QMessageBox.critical(None, "VirtScreen", QMessageBox.critical(None, "VirtScreen",
"Cannot detect home directory.") "Cannot detect home directory.")
sys.exit(1) sys.exit(1)
if not os.path.exists(HOME_PATH): if not os.path.exists(HOME_PATH):
try: try:
os.makedirs(HOME_PATH) os.makedirs(HOME_PATH)
except: except:
QMessageBox.critical(None, "VirtScreen", QMessageBox.critical(None, "VirtScreen",
"Cannot create ~/.virtscreen") "Cannot create ~/.virtscreen")
sys.exit(1) sys.exit(1)
import qt5reactor # pylint: disable=E0401 import qt5reactor # pylint: disable=E0401
qt5reactor.install() qt5reactor.install()
from twisted.internet import utils, reactor # pylint: disable=E0401 from twisted.internet import utils, reactor # pylint: disable=E0401
app.setWindowIcon(QIcon(ICON_PATH)) app.setWindowIcon(QIcon(ICON_PATH))
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material" os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
# os.environ["QT_QUICK_CONTROLS_STYLE"] = "Fusion" # os.environ["QT_QUICK_CONTROLS_STYLE"] = "Fusion"
# Register the Python type. Its URI is 'People', it's v1.0 and the type # Register the Python type. Its URI is 'People', it's v1.0 and the type
# will be called 'Person' in QML. # will be called 'Person' in QML.
qmlRegisterType(DisplayProperty, 'VirtScreen.DisplayProperty', 1, 0, 'DisplayProperty') qmlRegisterType(DisplayProperty, 'VirtScreen.DisplayProperty', 1, 0, 'DisplayProperty')