├── demo.png
├── assets
├── configure.png
├── reload_btn.png
├── user-home-symbolic.png
├── error_window.ui
└── main.ui
├── LICENSE
├── README.md
├── README_PT-BR.md
├── install_uninstall.py
└── main.py
/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hayukimori/scrcpy-pyqtgui/HEAD/demo.png
--------------------------------------------------------------------------------
/assets/configure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hayukimori/scrcpy-pyqtgui/HEAD/assets/configure.png
--------------------------------------------------------------------------------
/assets/reload_btn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hayukimori/scrcpy-pyqtgui/HEAD/assets/reload_btn.png
--------------------------------------------------------------------------------
/assets/user-home-symbolic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hayukimori/scrcpy-pyqtgui/HEAD/assets/user-home-symbolic.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 hayukimori
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/assets/error_window.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 372
10 | 259
11 |
12 |
13 |
14 | Error Window
15 |
16 |
17 | QMainWindow{
18 | background-color:rgb(1, 10, 15);
19 | }
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 | 16777215
28 | 50
29 |
30 |
31 |
32 | QLabel{
33 | color: white;
34 | }
35 |
36 |
37 | Erro Desconhecido
38 |
39 |
40 | true
41 |
42 |
43 |
44 | -
45 |
46 |
47 |
48 | 16777215
49 | 25
50 |
51 |
52 |
53 | QPushButton{
54 | background-color:rgb(80,80,80);
55 | border:none;
56 | border-radius:5px;
57 | color:rgb(255,255,255);
58 | }
59 |
60 |
61 | OK
62 |
63 |
64 | Return
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Scrcpy PyQt GUI
2 | > A simple interface to scrcpy made with Qt5
3 |
4 | 
5 | 
6 | 
7 |
8 |
9 |
10 | Scrcpy PyQtGUI is a Qt5 frontend to ease the use of scrcpy (currently run via command line).
11 |
12 | By not having access to the output of Scrcpy, there is the possibility of errors that do not appear on the screen or total crash in the interface (in case of running via Windows cmd)
13 |
14 | **Versão PT-BR: [README_PT-BR.md](README_PT-BR.md)**
15 | 
16 |
17 | ## Preparation and installation
18 | Some packages are necessary for the program to work, and they can be installed with the following commands:
19 |
20 |
21 | #### Ubuntu/Debian
22 |
23 | ```sh
24 | $ sudo apt-get install snapd python3-pip adb
25 | $ sudo snap install scrcpy
26 | $ pip3 install PyQt5 pure-python-adb
27 | ```
28 |
29 |
30 | #### Arch/Manjaro
31 | (NOTE: Both PARU and YAY can be used in this process, if you have either installed. In this case, I will be using YAY as an example)
32 |
33 | ```sh
34 | $ yay -S python3 python3-pip scrcpy
35 | $ sudo pacman -S android-tools
36 | $ pip3 install PyQt5 pure-python-adb
37 | ```
38 |
39 |
40 | ### Installation
41 | To install on linux distros, just run the `install_uninstall.py` script.
42 | I warn you that the installation of this version will take place in a different directory. It will be in `/home/{your_username}/.local/share/HayukiApps/`
43 |
44 | Also notice here that the commands _must_ be executed inside the folder;
45 |
46 | ```sh
47 | $ python install_uninstall.py
48 | ```
49 |
50 | #### Windows
51 | Unfortunately the installer is not ready for Windows yet, I will be developing it soon. But I think the program works fine if it has all dependencies and if `adb.exe` and `scrcpy.exe` are in the Windows PATH
52 |
53 | ## Common problems
54 |
55 | If `scrcpy_gui` doesn't start from terminal, check if `/home/user/.local/bin` is in $PATH, you can check with `$ echo $PATH`
56 |
57 | #### Default Bash
58 | If the path is not there, you can add to "~/.bashrc" the following line at the end of the file
59 |
60 | ```sh
61 | export PATH=$PATH:/home/{your username}/.local/bin
62 | ```
63 |
64 | #### Fish
65 | If you are using `fish`, it's a different case.
66 | You can add the path as follows:
67 |
68 | In your favorite text editor, add the following line to the `~/.config/fish/config.fish` file
69 |
70 | ```sh
71 | set -U fish_user_paths /home/{your user}/.local/bin $fish_user_paths
72 | ```
73 |
74 | ##### Other problems
75 |
76 | If the problem is not the one above, you can [open an issue](https://github.com/hayukimori/scrcpy-pyqtgui/issues/new). (PT BR or English)
77 |
78 | ## About
79 |
80 | Code and layout by _Ana Beatriz_ ([@hayukimori](https://twitter.com/hayukimori/))
81 |
--------------------------------------------------------------------------------
/README_PT-BR.md:
--------------------------------------------------------------------------------
1 | # Scrcpy GUI
2 | > Interface simples em Qt5 para o scrcpy
3 |
4 | 
5 | 
6 | 
7 |
8 | Scrcpy PyQtGUI é uma interface em Qt5 para facilitar o uso do Scrcpy (atualmente executado via linha de comando).
9 |
10 | Por não ter acesso ao output do Scrcpy, há a possibilidade de ocorrer erros que não apareçam na tela ou travamento total da interface (no caso de rodar via cmd do Windows)
11 |
12 | 
13 |
14 | ## Preparação e Instalação
15 | Alguns pacotes são necessários para o funcionamento de programa, e podem ser instalados com os seguintes comandos:
16 |
17 |
18 | #### Ubuntu/Debian
19 |
20 | ```sh
21 | $ sudo apt-get install snapd python3-pip adb
22 | $ sudo snap install scrcpy
23 | $ pip3 install PyQt5 pure-python-adb
24 | ```
25 |
26 |
27 | #### Arch/Manjaro
28 | (NOTA: Tanto PARU quanto YAY pode ser utilizado neste processo, caso tenha algum dos dois instalado. Neste caso, estarei utilizando YAY como exemplo)
29 |
30 | ```sh
31 | $ yay -S python3 python3-pip scrcpy
32 | $ sudo pacman -S android-tools
33 | $ pip3 install PyQt5 pure-python-adb
34 | ```
35 |
36 |
37 | ### Instalação
38 |
39 | #### Linux
40 | Para fazer a instalação em distros linux, basta rodar o script `install_uninstall.py` e seguir os passos.
41 | Deixo avisado que a instalação desta versão ocorrerá num diretório diferente. Ficará no `/home/{seu_usuário}/.local/share/HayukiApps/`
42 |
43 | Aviso aqui também que os comandos _devem_ ser executados dentro da pasta;
44 | ```sh
45 | $ python install_uninstall.py
46 | ```
47 |
48 | #### Windows
49 | Infelizmente o instalador ainda não está pronto para o Windows, estarei desenvolvendo em breve. Mas creio que o programa funcione bem se estiver com todas as dependências e se `adb.exe` e `scrcpy.exe` estiverem no PATH do Windows
50 |
51 |
52 | ## Uso
53 | Para lançar o programa, pode utilizar o ícone que é criado após a instalação (linux), ou iniciar através do terminal pelo seguinte comando;
54 |
55 | ```sh
56 | $ scrcpy_gui
57 | ```
58 |
59 |
60 |
61 | ## Solução de problemas
62 |
63 | Caso `scrcpy_gui` não inicie pelo terminal, verifique se `/home/usuario/.local/bin` está em $PATH, você pode verificar com `$ echo $PATH`
64 |
65 | #### Bash padrão
66 | Caso o path não esteja, você pode adicionar ao "~/.bashrc" a seguinte linha no final do arquivo
67 | ```sh
68 | export PATH=$PATH:/home/{seu usuario}/.local/bin
69 | ```
70 |
71 | #### Fish
72 | Se você estiver utilizando o `fish`, o caso é outro
73 | Você pode adicionar o path da seguinte forma:
74 |
75 |
76 | No seu editor de texto preferido, adicione a seguinte linha no arquivo `~/.config/fish/config.fish`
77 | ```sh
78 | set -U fish_user_paths /home/{seu usuário}/.local/bin $fish_user_paths
79 | ```
80 |
81 | ##### Outros problemas
82 | Caso seu problema não seja o de cima, você pode [abrir uma issue](https://github.com/hayukimori/scrcpy-pyqtgui/issues/new).
83 |
84 |
85 |
86 |
87 | ## Sobre
88 |
89 | Código e layout por _Ana Beatriz_ ([@hayukimori](https://twitter.com/hayukimori/))
90 |
--------------------------------------------------------------------------------
/install_uninstall.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import os, sys, platform
3 |
4 | USER_SYSTEM = platform.system()
5 | VAR_HOME = os.getenv('HOME')
6 |
7 | ################## NEW -- LINUX BASED ########################
8 | linux_default_appbase_instalation_path = VAR_HOME + '/.local/share/HayukiApps/scrcpy_pyqtgui/'
9 | linux_default_assets_folder = linux_default_appbase_instalation_path + '/assets/'
10 | linux_default_shell_script = VAR_HOME + '/.local/bin/scrcpy_pyqtgui'
11 | linux_default_desktop_path = VAR_HOME + '/.local/share/applications/'
12 | linux_default_desktop_filename = 'scrcpy_pyqtgui'
13 | ################################################################
14 |
15 |
16 | # GLB => GLOBAL --- abbreviated global variables
17 | glb_ldai = linux_default_appbase_instalation_path
18 | glb_laf = linux_default_assets_folder
19 | glb_ldsc = linux_default_shell_script
20 | glb_ddp = linux_default_desktop_path
21 | a_files = ['error_window.ui', 'main.ui', 'reload_btn.png', 'configure.png', 'user-home-symbolic.png']
22 |
23 |
24 |
25 | def infoAlert(info: str, error=False):
26 | if error == False:
27 | print('[INFO] ' + info)
28 |
29 | elif error == True:
30 | print('[ERROR] ' + info)
31 |
32 | try:
33 | if type(error) != bool:
34 | if error.lower() == "alert":
35 | print(f"< {error.lower()} > " + info)
36 |
37 | except Exception as e:
38 | infoAlert(str(e), error=True)
39 |
40 | class ManageInstaller():
41 | def __init__(self, operational_system_base='linux'):
42 | self.osb = operational_system_base;
43 |
44 |
45 | if self.osb.lower() == 'linux':
46 | self.installerMain = LinuxInstaller()
47 |
48 | else:
49 | infoAlert(info="Non Linux-based system detected; Unfortunately this program don't have a installer for this system (not yet).\n\n Try to contact me on social networks:\n\n-Twitter: https://twitter.com/hayukimori\n-Discord: hayukimori#0599\nGitHub: https://github.com/hayukimori", error="alert")
50 |
51 | class LinuxInstaller():
52 | def __init__(self):
53 | if self.verifyExistingInstallation() != True:
54 | self.startInstaller()
55 |
56 | else:
57 | self.uninstall(quest=True)
58 |
59 |
60 | def startInstaller(self):
61 |
62 | if self.verifyLocalFiles() == False:
63 | infoAlert(f"Some files couldn't be found, please verify files and try again;\nRequired files: {a_files}", error=True)
64 |
65 | else:
66 | try:
67 |
68 | # => Informing about package
69 | package_info = f"\n=============================================\nApp: Scrcpy PtQtGui\nApp: scrcpy_pyqtgui,\nFont: github\nCreator: hayukimori\n\nInstallation Path: {linux_default_appbase_instalation_path}\nStatus: installing\n=============================================\n"
70 | infoAlert(package_info, error=False)
71 |
72 |
73 |
74 | # => Creating Directories (HayukiApps, assets)
75 | infoAlert(f"Creating directiories:\n {linux_default_appbase_instalation_path}\n{linux_default_assets_folder}", error=False)
76 | os.system('mkdir -p ' + linux_default_appbase_instalation_path)
77 | os.system('mkdir -p ' + linux_default_assets_folder)
78 |
79 |
80 | # => Moving files to paths
81 | infoAlert("Moving files (assets)", error=False)
82 | for file in a_files:
83 | print(file)
84 | os.system(f"cp assets/{file} " + linux_default_assets_folder)
85 |
86 |
87 | infoAlert("Moving main files", error=False)
88 | for file in ['main.py', 'install_uninstall.py']:
89 | os.system(f'cp {file} ' + linux_default_appbase_instalation_path)
90 |
91 |
92 |
93 | # => Making Shell Script
94 |
95 | # Checks if ".local/bin/" is in $PATH
96 | if self.localbin_in_SystemPath() == False:
97 | infoAlert(f"'{VAR_HOME}/.local/bin' isn't in PATH. To start this application using terminal, you'll need to add in $PATH. See README.md to see how to make it", error=False)
98 | infoAlert("Creating shell script", error=False)
99 |
100 |
101 | self.makeShellScript()
102 |
103 |
104 | # => Creating desktop file
105 | infoAlert("Creating desktop file", error=False)
106 | dfileText = f'''[Desktop Entry]\nVersion=1.0\nType=Application\nName=Scrcpy Gui\nComment=Scrcpy PyQt5 gui\nIcon=smartphone\nExec=python main.py\nPath={linux_default_appbase_instalation_path}\nTerminal=false\nStartupNotify=true\nCategories=AudioVideo;nUtility;'''
107 |
108 |
109 | with open(linux_default_desktop_path + linux_default_desktop_filename + '.desktop', 'w') as df:
110 | df.write(dfileText)
111 | df.close()
112 |
113 |
114 |
115 |
116 |
117 | except Exception as e:
118 | infoAlert(str(e) + '\n', error=True)
119 |
120 | def verifyLocalFiles(self):
121 |
122 | results = []
123 |
124 | for a in a_files:
125 | if os.path.exists("./assets/" + a) == True:
126 | results.append(True)
127 |
128 |
129 | if all_true(results):
130 | return True
131 | else:
132 | return False
133 |
134 |
135 | def verifyExistingInstallation(self):
136 | # for newer version Only
137 | if os.path.exists(linux_default_appbase_instalation_path) == True:
138 | return True
139 |
140 | else:
141 | return False
142 |
143 | def uninstall(self, quest=True):
144 | print("=====================SCRCPY PYQT GUI FOUND IN SYSTEM ==========================")
145 | print(f"Installation found in {VAR_HOME}/.local/share/HayukiApps/")
146 | uinput = input("Uninstall current version or Update (UPdate / UNinstall)\n((default: Update)): ")
147 | print("===============================================================================")
148 |
149 | uinput_no_spaces = uinput.replace(" ", '')
150 |
151 | if uinput_no_spaces.lower().startswith('un'):
152 | os.system(f'rm -rf ' + linux_default_appbase_instalation_path)
153 | os.system(f'rm -rf ' + linux_default_desktop_path + linux_default_desktop_filename)
154 |
155 |
156 | else:
157 | os.system(f'rm -rf ' + linux_default_appbase_instalation_path)
158 | self.startInstaller()
159 |
160 |
161 | def makeShellScript(self):
162 | script_text = f'''#!/bin/bash\ncd {linux_default_appbase_instalation_path}/\npython main.py'''
163 |
164 |
165 | with open(linux_default_shell_script, 'w') as ss:
166 | ss.write(script_text)
167 | ss.close()
168 | os.system(f"chmod +x {linux_default_shell_script}")
169 |
170 |
171 | def localbin_in_SystemPath(self):
172 | path_linux_var = os.getenv('PATH')
173 |
174 | if '/.local/bin' in path_linux_var:
175 | return True
176 | else:
177 | return False
178 |
179 |
180 | def all_true(items):
181 | return all(x == True for x in items)
182 |
183 |
184 | if __name__ == "__main__":
185 | Installer = ManageInstaller(operational_system_base=USER_SYSTEM)
186 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import os, sys, re, subprocess;
2 | from PyQt5 import uic, QtWidgets
3 | from PyQt5.QtCore import *
4 | from PyQt5.QtGui import *
5 | from PyQt5.QtWidgets import *
6 |
7 | from ppadb.client import Client as AdbClient
8 |
9 | linux_nobrake = "&" # This works for PowerShell too
10 | nobrake = linux_nobrake
11 |
12 | adb = AdbClient(host="127.0.0.1", port=5037)
13 | app = QtWidgets.QApplication([])
14 |
15 |
16 | class MainProgram:
17 |
18 | def get_devices(win_devices):
19 | try:
20 | devices = adb.devices()
21 |
22 | if len(devices) == 0:
23 | ErrorShower("No devices connected")
24 |
25 | for device in devices:
26 | win_devices.addItem(device.serial)
27 |
28 | except Exception as e:
29 | ErrorShower(error=str(e))
30 |
31 |
32 | def normalStart(self):
33 |
34 | try:
35 |
36 | space = " "
37 |
38 | device = window.normal_devices.currentText()
39 | bitrate = window.normal_bitrate.text()
40 | fullscreen = window.normal_fullscreen.isChecked()
41 | view_only = window.normal_view_only.isChecked()
42 | borderless = window.normal_borderless.isChecked()
43 | render = window.normal_render.currentText()
44 |
45 | code = 'scrcpy' + space
46 |
47 | if fullscreen == True:
48 | code = code + '--fullscreen' + space
49 |
50 | if view_only == True:
51 | code = code + '--no-control' + space
52 |
53 | if borderless == True:
54 | code = code + '--window borderless' + space
55 |
56 |
57 | final_code = f'''{code} --serial {device} -b {bitrate} --render-driver="{render}"''' + nobrake
58 | os.system(final_code)
59 |
60 | except Exception as e:
61 | ErrorShower(str(e))
62 |
63 |
64 | def otgStart(self):
65 | try:
66 |
67 | space = " "
68 |
69 | device = window.otg_devices.currentText()
70 | bitrate = window.otg_bitrate.text()
71 | fullscreen = window.otg_fullscreen.isChecked()
72 | borderless = window.otg_borderless.isChecked()
73 | render = window.otg_render.currentText()
74 |
75 | code = 'scrcpy' + space
76 |
77 | if fullscreen == True:
78 | code = code + '--fullscreen' + space
79 |
80 | if borderless == True:
81 | code = code + '--window borderless' + space
82 |
83 |
84 | final_code = f'''{code} -K -M --serial {device} -b {bitrate} --render-driver="{render} "''' + nobrake
85 | os.system(final_code)
86 |
87 | except Exception as e:
88 | ErrorShower(str(e))
89 |
90 |
91 | def gameStart(self):
92 | try:
93 |
94 | space = " "
95 |
96 | device = window.game_devices.currentText()
97 | bitrate = window.game_bitrate.text()
98 | fullscreen = window.game_fullscreen.isChecked()
99 | borderless = window.game_borderless.isChecked()
100 | no_otg = window.game_no_otg.isChecked()
101 | render = window.game_render.currentText()
102 |
103 |
104 | code = 'scrcpy' + space
105 |
106 | if fullscreen == True:
107 | code = code + '--fullscreen' + space
108 |
109 |
110 | if borderless == True:
111 | code = code + '--window borderless' + space
112 |
113 |
114 | if no_otg != True:
115 | code = code + '-K -M'
116 |
117 |
118 | final_code = f'''{code} --serial {device} -b {bitrate} --render-driver="{render}"''' + nobrake
119 | os.system(final_code)
120 |
121 | except Exception as e:
122 | ErrorShower(str(e))
123 |
124 |
125 | def manualStart(self):
126 | try:
127 |
128 | space = " "
129 |
130 | device = window.manual_devices.currentText()
131 | bitrate = window.manual_bitrate.text()
132 | fullscreen = window.manual_fullscreen.isChecked()
133 | view_only = window.manual_view_only.isChecked()
134 | borderless = window.manual_borderless.isChecked()
135 | render = window.manual_render.currentText()
136 | add_args = window.manual_args.toPlainText()
137 |
138 | code = 'scrcpy' + space
139 |
140 | if fullscreen == True:
141 | code = code + '--fullscreen' + space
142 |
143 | if view_only == True:
144 | code = code + '--no-control' + space
145 |
146 | if borderless == True:
147 | code = code + '--window borderless' + space
148 |
149 | if len(add_args) >= 1:
150 | code = code + add_args + space
151 |
152 |
153 | final_code = f'''{code} --serial {device} -b {bitrate} --render-driver="{render}"''' + nobrake
154 | os.system(final_code)
155 |
156 | except Exception as e:
157 | ErrorShower(str(e))
158 |
159 |
160 |
161 |
162 | class WindowManager():
163 |
164 | def defineFlags():
165 | window.setWindowFlags(Qt.FramelessWindowHint)
166 | window.setAttribute(Qt.WA_TranslucentBackground)
167 |
168 | def showMain():
169 | window.show()
170 |
171 |
172 | def _home_page():
173 | window.stackedWidget.setCurrentIndex(0)
174 |
175 | def _normal_page():
176 | window.stackedWidget.setCurrentIndex(1)
177 |
178 | WindowManager.reZero(window.normal_devices)
179 | MainProgram.get_devices(window.normal_devices)
180 |
181 | def _otg_page():
182 | window.stackedWidget.setCurrentIndex(2)
183 |
184 | WindowManager.reZero(window.otg_devices)
185 | MainProgram.get_devices(window.otg_devices)
186 |
187 | def _game_page():
188 | window.stackedWidget.setCurrentIndex(3)
189 |
190 | WindowManager.reZero(window.game_devices)
191 | MainProgram.get_devices(window.game_devices)
192 |
193 | def _manual_page():
194 | window.stackedWidget.setCurrentIndex(4)
195 |
196 | WindowManager.reZero(window.manual_devices)
197 | MainProgram.get_devices(window.manual_devices)
198 |
199 |
200 | def _confs_page():
201 | window.stackedWidget.setCurrentIndex(5)
202 |
203 |
204 |
205 |
206 | def _reload_normal_d():
207 | WindowManager.reZero(window.normal_devices)
208 | MainProgram.get_devices(window.normal_devices)
209 |
210 |
211 | def _reload_otg_d():
212 | WindowManager.reZero(window.otg_devices)
213 | MainProgram.get_devices(window.otg_devices)
214 |
215 | def _reload_game_d():
216 | WindowManager.reZero(window.game_devices)
217 | MainProgram.get_devices(window.game_devices)
218 |
219 |
220 | def _reload_manual_d():
221 | WindowManager.reZero(window.manual_devices)
222 | MainProgram.get_devices(window.manual_devices)
223 |
224 |
225 |
226 |
227 | def reZero(win_devices):
228 | while len(win_devices) > 0:
229 | win_devices.removeItem(0)
230 |
231 |
232 |
233 |
234 | class ErrorShower():
235 | def __init__(self, error, windowed=True):
236 | self.error = error
237 | self.windowed = windowed
238 |
239 | if windowed == True:
240 | errorWindow.text.setText(str(error))
241 | errorWindow.show()
242 | else:
243 | print(f" {str(error)}")
244 |
245 |
246 |
247 | window = uic.loadUi("assets/main.ui")
248 | errorWindow = uic.loadUi("assets/error_window.ui")
249 | window.exit_button.clicked.connect(sys.exit)
250 |
251 |
252 | # Button Functions
253 | window.home_btn.clicked.connect(WindowManager._home_page)
254 | window.normal_btn.clicked.connect(WindowManager._normal_page)
255 | window.otg_btn.clicked.connect(WindowManager._otg_page)
256 | window.game_btn.clicked.connect(WindowManager._game_page)
257 | window.manual_btn.clicked.connect(WindowManager._manual_page)
258 | window.configure_btn.clicked.connect(WindowManager._confs_page)
259 |
260 | window.minimize_btn.clicked.connect(window.showMinimized)
261 | errorWindow.ok_btn.clicked.connect(errorWindow.close)
262 |
263 | # Reload Buttons
264 | window.normal_reload_btn.clicked.connect(WindowManager._reload_normal_d)
265 | window.otg_reload_btn.clicked.connect(WindowManager._reload_otg_d)
266 | window.game_reload_btn.clicked.connect(WindowManager._reload_game_d)
267 | window.manual_reload_btn.clicked.connect(WindowManager._reload_manual_d)
268 |
269 |
270 | # Start Buttons
271 | window.normal_start.clicked.connect(MainProgram.normalStart)
272 | window.otg_start.clicked.connect(MainProgram.otgStart)
273 | window.game_start.clicked.connect(MainProgram.gameStart)
274 | window.manual_start.clicked.connect(MainProgram.manualStart)
275 |
276 |
277 |
278 |
279 | if __name__ == "__main__":
280 | WindowManager.defineFlags()
281 | WindowManager.showMain()
282 | app.exec()
283 |
--------------------------------------------------------------------------------
/assets/main.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 962
10 | 499
11 |
12 |
13 |
14 | Scrcpy PyQt5 GUI
15 |
16 |
17 |
18 |
19 | 0
20 |
21 |
22 | 4
23 |
24 |
25 | 0
26 |
27 |
28 | 4
29 |
30 |
31 | 0
32 |
33 | -
34 |
35 |
36 | QFrame{
37 | background-color: rgb(0,0,0);
38 | border-radius:10%;
39 | }
40 |
41 |
42 | QFrame::StyledPanel
43 |
44 |
45 | QFrame::Raised
46 |
47 |
48 |
49 |
50 | 850
51 | 30
52 | 51
53 | 41
54 |
55 |
56 |
57 |
58 | 12
59 |
60 |
61 |
62 | QPushButton{
63 | color: rgb(119, 118, 123);
64 | background: none;
65 | border: none;
66 | border-radius: 5%;
67 | }
68 |
69 | QPushButton:hover{
70 | background-color: rgb(22,22,22);
71 | color: rgb(255,255,255);
72 | }
73 |
74 |
75 | -
76 |
77 |
78 |
79 |
80 |
81 | 900
82 | 30
83 | 51
84 | 41
85 |
86 |
87 |
88 | QPushButton{
89 | color: rgb(119, 118, 123);
90 | background: none;
91 | border: none;
92 | border-radius: 5%;
93 | }
94 |
95 | QPushButton:hover{
96 | background-color: rgb(237, 51, 59);
97 | color: rgb(255,255,255);
98 | }
99 |
100 |
101 | X
102 |
103 |
104 |
105 |
106 |
107 | 20
108 | 120
109 | 51
110 | 331
111 |
112 |
113 |
114 | QGroupBox{
115 | background-color: rgba(53, 132, 228,190);
116 | border-radius: 10%;
117 | }
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 | 0
126 | 20
127 | 51
128 | 51
129 |
130 |
131 |
132 | QPushButton{
133 | background-color: none;
134 | border: none;
135 | }
136 |
137 | QPushButton:hover{
138 | background-color: rgb(0,0,0);
139 | border-radius: 10px;
140 | }
141 |
142 |
143 |
144 |
145 |
146 |
147 | configure.pngconfigure.png
148 |
149 |
150 |
151 |
152 |
153 | 0
154 | 70
155 | 51
156 | 51
157 |
158 |
159 |
160 | QPushButton{
161 | background-color: none;
162 | border: none;
163 | }
164 |
165 | QPushButton:hover{
166 | background-color: rgb(0,0,0);
167 | border-radius: 10px;
168 | }
169 |
170 |
171 |
172 |
173 |
174 |
175 | user-home-symbolic.pnguser-home-symbolic.png
176 |
177 |
178 |
179 |
180 |
181 |
182 | 90
183 | 120
184 | 851
185 | 331
186 |
187 |
188 |
189 | QStackedWidget{
190 | background:rgba(53, 132, 228,190);
191 | }
192 |
193 |
194 | 0
195 |
196 |
197 |
198 |
199 |
200 | 40
201 | 10
202 | 151
203 | 311
204 |
205 |
206 |
207 | QFrame{
208 | background-color: rgb(22,22,22);
209 | }
210 |
211 |
212 | QFrame::StyledPanel
213 |
214 |
215 | QFrame::Raised
216 |
217 |
218 |
219 |
220 | 10
221 | 10
222 | 131
223 | 291
224 |
225 |
226 |
227 | QPushButton{
228 | background-color: white;
229 | }
230 |
231 | QPushButton:hover{
232 | background-color: rgb(192, 191, 188);
233 | }
234 |
235 |
236 | Normal
237 |
238 |
239 |
240 |
241 |
242 |
243 | 240
244 | 10
245 | 151
246 | 311
247 |
248 |
249 |
250 | QFrame{
251 | background-color: rgb(22,22,22);
252 | }
253 |
254 |
255 | QFrame::StyledPanel
256 |
257 |
258 | QFrame::Raised
259 |
260 |
261 |
262 |
263 | 10
264 | 10
265 | 131
266 | 291
267 |
268 |
269 |
270 | QPushButton{
271 | background-color: white;
272 | }
273 |
274 | QPushButton:hover{
275 | background-color: rgb(192, 191, 188);
276 | }
277 |
278 |
279 | OTG Mode
280 |
281 |
282 |
283 |
284 |
285 |
286 | 450
287 | 10
288 | 151
289 | 311
290 |
291 |
292 |
293 | QFrame{
294 | background-color: rgb(22,22,22);
295 | }
296 |
297 |
298 | QFrame::StyledPanel
299 |
300 |
301 | QFrame::Raised
302 |
303 |
304 |
305 |
306 | 10
307 | 10
308 | 131
309 | 291
310 |
311 |
312 |
313 | QPushButton{
314 | background-color: white;
315 | }
316 |
317 | QPushButton:hover{
318 | background-color: rgb(192, 191, 188);
319 | }
320 |
321 |
322 | Game Mode
323 |
324 |
325 | false
326 |
327 |
328 | false
329 |
330 |
331 | false
332 |
333 |
334 |
335 |
336 |
337 |
338 | 660
339 | 10
340 | 151
341 | 311
342 |
343 |
344 |
345 | QFrame{
346 | background-color: rgb(22,22,22);
347 | }
348 |
349 |
350 | QFrame::StyledPanel
351 |
352 |
353 | QFrame::Raised
354 |
355 |
356 |
357 |
358 | 10
359 | 10
360 | 131
361 | 291
362 |
363 |
364 |
365 | QPushButton{
366 | background-color: white;
367 | }
368 |
369 | QPushButton:hover{
370 | background-color: rgb(192, 191, 188);
371 | }
372 |
373 |
374 | Manual
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 | 10
384 | 10
385 | 151
386 | 311
387 |
388 |
389 |
390 | QFrame{
391 | background-color: rgb(22,22,22);
392 | }
393 |
394 |
395 | QFrame::StyledPanel
396 |
397 |
398 | QFrame::Raised
399 |
400 |
401 |
402 |
403 | 10
404 | 10
405 | 131
406 | 291
407 |
408 |
409 |
410 | QLabel{
411 | background-color: white;
412 | }
413 |
414 |
415 | Normal
416 |
417 |
418 | Qt::AlignCenter
419 |
420 |
421 |
422 |
423 |
424 |
425 | 180
426 | 10
427 | 661
428 | 311
429 |
430 |
431 |
432 | QFrame{
433 | color: rgb(255,255,255);
434 | }
435 |
436 |
437 | QFrame::StyledPanel
438 |
439 |
440 | QFrame::Raised
441 |
442 |
443 |
444 |
445 | 20
446 | 20
447 | 61
448 | 41
449 |
450 |
451 |
452 | Device
453 |
454 |
455 |
456 |
457 |
458 | 80
459 | 30
460 | 571
461 | 21
462 |
463 |
464 |
465 | QComboBox{
466 | color:white;
467 | border: none;
468 | padding-top: 2px;
469 | padding-bottom: 5px;
470 | background-color:rgb(22, 22, 22);
471 | border-radius:3px;
472 | }
473 |
474 |
475 |
476 |
477 |
478 | 20
479 | 70
480 | 61
481 | 51
482 |
483 |
484 |
485 | Bitrate
486 |
487 |
488 |
489 |
490 |
491 | 80
492 | 80
493 | 91
494 | 26
495 |
496 |
497 |
498 | QLineEdit{
499 | color:white;
500 | border: none;
501 | padding-top: 2px;
502 | padding-bottom: 5px;
503 | background-color:rgb(22, 22, 22);
504 | border-radius:3px;
505 | }
506 |
507 |
508 | 8000000
509 |
510 |
511 |
512 |
513 |
514 | 180
515 | 90
516 | 41
517 | 18
518 |
519 |
520 |
521 | Hz
522 |
523 |
524 |
525 |
526 |
527 | 380
528 | 80
529 | 141
530 | 31
531 |
532 |
533 |
534 |
535 | 8
536 |
537 |
538 |
539 | PointingHandCursor
540 |
541 |
542 | QCheckBox{
543 | color:white;
544 | border: none;
545 | padding-left:4px;
546 | background-color:rgb(22, 22, 22);
547 | border-radius:3px;
548 | }
549 | QCheckBox::indicator
550 | {
551 | border-radius: 0.25em;
552 | border: 0.1em solid rgb(114, 159, 207);
553 | }
554 |
555 | QCheckBox::indicator::checked
556 | {
557 | background-color:rgb(114, 159, 207);
558 | }
559 |
560 |
561 | Fullscreen
562 |
563 |
564 | Ctrl+F
565 |
566 |
567 |
568 |
569 |
570 | 220
571 | 80
572 | 151
573 | 31
574 |
575 |
576 |
577 |
578 | 8
579 |
580 |
581 |
582 | PointingHandCursor
583 |
584 |
585 | true
586 |
587 |
588 | QCheckBox{
589 | color:white;
590 | border: none;
591 | padding-left:4px;
592 | background-color:rgb(22, 22, 22);
593 | border-radius:3px;
594 | }
595 | QCheckBox::indicator
596 | {
597 | border-radius: 0.25em;
598 | border: 0.1em solid rgb(114, 159, 207);
599 | }
600 |
601 | QCheckBox::indicator::checked
602 | {
603 | background-color:rgb(114, 159, 207);
604 | }
605 |
606 |
607 | View Only
608 |
609 |
610 | Ctrl+X
611 |
612 |
613 |
614 |
615 |
616 | 530
617 | 80
618 | 121
619 | 31
620 |
621 |
622 |
623 |
624 | 8
625 |
626 |
627 |
628 | PointingHandCursor
629 |
630 |
631 | true
632 |
633 |
634 | QCheckBox{
635 | color:white;
636 | border: none;
637 | padding-left:4px;
638 | background-color:rgb(22, 22, 22);
639 | border-radius:3px;
640 | }
641 | QCheckBox::indicator
642 | {
643 | border-radius: 0.25em;
644 | border: 0.1em solid rgb(114, 159, 207);
645 | }
646 |
647 | QCheckBox::indicator::checked
648 | {
649 | background-color:rgb(114, 159, 207);
650 | }
651 |
652 |
653 | Borderless
654 |
655 |
656 | Ctrl+B
657 |
658 |
659 |
660 |
661 |
662 | 20
663 | 140
664 | 121
665 | 18
666 |
667 |
668 |
669 | Render Driver
670 |
671 |
672 |
673 |
674 |
675 | 120
676 | 140
677 | 531
678 | 21
679 |
680 |
681 |
682 |
683 | 0
684 | 0
685 |
686 |
687 |
688 |
689 | 16777215
690 | 16777215
691 |
692 |
693 |
694 |
695 | 8
696 |
697 |
698 |
699 | PointingHandCursor
700 |
701 |
702 | QComboBox
703 | {
704 | color:white;
705 | border: none;
706 | padding-top: 2px;
707 | padding-bottom: 5px;
708 | background-color:rgb(22, 22, 22);
709 | border-radius:3px;
710 | }
711 |
712 |
-
713 |
714 | opengles2
715 |
716 |
717 | -
718 |
719 | opengles
720 |
721 |
722 | -
723 |
724 | opengl
725 |
726 |
727 | -
728 |
729 | direct3d
730 |
731 |
732 | -
733 |
734 | metal
735 |
736 |
737 | -
738 |
739 | software
740 |
741 |
742 |
743 |
744 |
745 |
746 | 20
747 | 190
748 | 631
749 | 31
750 |
751 |
752 |
753 | QLabel{
754 | opacity: .5;
755 | }
756 |
757 |
758 | <html><head/><body><p><span style=" color:#ffff00;">* If you're using Windows, is recommended to use 'direct3d' render driver</span></p></body></html>
759 |
760 |
761 |
762 |
763 |
764 | 20
765 | 250
766 | 141
767 | 31
768 |
769 |
770 |
771 |
772 | 16777215
773 | 16777215
774 |
775 |
776 |
777 | QPushButton{
778 | background-color:rgba(53, 132, 228,190);
779 | border: none;
780 | border-radius:10px;
781 | color:white;
782 | }
783 |
784 | QPushButton:hover{
785 | background-color:rgb(32, 74, 135);
786 | }
787 |
788 |
789 | Reload Devices
790 |
791 |
792 |
793 | reload_btn.pngreload_btn.png
794 |
795 |
796 | Ctrl+R
797 |
798 |
799 |
800 |
801 |
802 | 520
803 | 250
804 | 121
805 | 31
806 |
807 |
808 |
809 |
810 | 16777215
811 | 16777215
812 |
813 |
814 |
815 | PointingHandCursor
816 |
817 |
818 | QPushButton{
819 | color:rgb(255,255,255);
820 | background-color:rgba(53, 132, 228,190);
821 | border: none;
822 | border-radius:10px;
823 | }
824 |
825 | QPushButton:hover{
826 | background:rgb(32, 74, 135);
827 | }
828 |
829 |
830 | Start
831 |
832 |
833 |
834 | 60
835 | 60
836 |
837 |
838 |
839 | Ctrl+Return
840 |
841 |
842 |
843 |
844 |
845 |
846 |
847 |
848 | 10
849 | 10
850 | 151
851 | 311
852 |
853 |
854 |
855 | QFrame{
856 | background-color: rgb(22,22,22);
857 | }
858 |
859 |
860 | QFrame::StyledPanel
861 |
862 |
863 | QFrame::Raised
864 |
865 |
866 |
867 |
868 | 10
869 | 10
870 | 131
871 | 291
872 |
873 |
874 |
875 | QLabel{
876 | background-color: white;
877 | }
878 |
879 |
880 | OTG Mode
881 |
882 |
883 | Qt::AlignCenter
884 |
885 |
886 |
887 |
888 |
889 |
890 | 180
891 | 10
892 | 661
893 | 311
894 |
895 |
896 |
897 | QFrame{
898 | color: rgb(255,255,255);
899 | }
900 |
901 |
902 | QFrame::StyledPanel
903 |
904 |
905 | QFrame::Raised
906 |
907 |
908 |
909 |
910 | 20
911 | 20
912 | 61
913 | 41
914 |
915 |
916 |
917 | Device
918 |
919 |
920 |
921 |
922 |
923 | 80
924 | 30
925 | 581
926 | 21
927 |
928 |
929 |
930 | QComboBox{
931 | color:white;
932 | border: none;
933 | padding-top: 2px;
934 | padding-bottom: 5px;
935 | background-color:rgb(22, 22, 22);
936 | border-radius:3px;
937 | }
938 |
939 |
940 |
941 |
942 |
943 | 20
944 | 70
945 | 61
946 | 51
947 |
948 |
949 |
950 | Bitrate
951 |
952 |
953 |
954 |
955 |
956 | 80
957 | 80
958 | 91
959 | 26
960 |
961 |
962 |
963 | QLineEdit{
964 | color:white;
965 | border: none;
966 | padding-top: 2px;
967 | padding-bottom: 5px;
968 | background-color:rgb(22, 22, 22);
969 | border-radius:3px;
970 | }
971 |
972 |
973 | 8000000
974 |
975 |
976 |
977 |
978 |
979 | 180
980 | 90
981 | 41
982 | 18
983 |
984 |
985 |
986 | Hz
987 |
988 |
989 |
990 |
991 |
992 | 220
993 | 80
994 | 141
995 | 31
996 |
997 |
998 |
999 |
1000 | 8
1001 |
1002 |
1003 |
1004 | PointingHandCursor
1005 |
1006 |
1007 | QCheckBox{
1008 | color:white;
1009 | border: none;
1010 | padding-left:4px;
1011 | background-color:rgb(22, 22, 22);
1012 | border-radius:3px;
1013 | }
1014 | QCheckBox::indicator
1015 | {
1016 | border-radius: 0.25em;
1017 | border: 0.1em solid rgb(114, 159, 207);
1018 | }
1019 |
1020 | QCheckBox::indicator::checked
1021 | {
1022 | background-color:rgb(114, 159, 207);
1023 | }
1024 |
1025 |
1026 | Fullscreen
1027 |
1028 |
1029 | Ctrl+F
1030 |
1031 |
1032 |
1033 |
1034 |
1035 | 380
1036 | 80
1037 | 121
1038 | 31
1039 |
1040 |
1041 |
1042 |
1043 | 8
1044 |
1045 |
1046 |
1047 | PointingHandCursor
1048 |
1049 |
1050 | true
1051 |
1052 |
1053 | QCheckBox{
1054 | color:white;
1055 | border: none;
1056 | padding-left:4px;
1057 | background-color:rgb(22, 22, 22);
1058 | border-radius:3px;
1059 | }
1060 | QCheckBox::indicator
1061 | {
1062 | border-radius: 0.25em;
1063 | border: 0.1em solid rgb(114, 159, 207);
1064 | }
1065 |
1066 | QCheckBox::indicator::checked
1067 | {
1068 | background-color:rgb(114, 159, 207);
1069 | }
1070 |
1071 |
1072 | Borderless
1073 |
1074 |
1075 | Ctrl+B
1076 |
1077 |
1078 |
1079 |
1080 |
1081 | 20
1082 | 140
1083 | 121
1084 | 18
1085 |
1086 |
1087 |
1088 | Render Driver
1089 |
1090 |
1091 |
1092 |
1093 |
1094 | 120
1095 | 140
1096 | 541
1097 | 21
1098 |
1099 |
1100 |
1101 |
1102 | 0
1103 | 0
1104 |
1105 |
1106 |
1107 |
1108 | 16777215
1109 | 16777215
1110 |
1111 |
1112 |
1113 |
1114 | 8
1115 |
1116 |
1117 |
1118 | PointingHandCursor
1119 |
1120 |
1121 | QComboBox
1122 | {
1123 | color:white;
1124 | border: none;
1125 | padding-top: 2px;
1126 | padding-bottom: 5px;
1127 | background-color:rgb(22, 22, 22);
1128 | border-radius:3px;
1129 | }
1130 |
1131 | -
1132 |
1133 | opengles2
1134 |
1135 |
1136 | -
1137 |
1138 | opengles
1139 |
1140 |
1141 | -
1142 |
1143 | opengl
1144 |
1145 |
1146 | -
1147 |
1148 | direct3d
1149 |
1150 |
1151 | -
1152 |
1153 | metal
1154 |
1155 |
1156 | -
1157 |
1158 | software
1159 |
1160 |
1161 |
1162 |
1163 |
1164 |
1165 | 20
1166 | 190
1167 | 631
1168 | 31
1169 |
1170 |
1171 |
1172 | QLabel{
1173 | opacity: .5;
1174 | }
1175 |
1176 |
1177 | <html><head/><body><p><span style=" color:#ffff00;">* If you're using Windows, is recommended to use 'direct3d' render driver</span></p></body></html>
1178 |
1179 |
1180 |
1181 |
1182 |
1183 | 20
1184 | 250
1185 | 141
1186 | 31
1187 |
1188 |
1189 |
1190 |
1191 | 16777215
1192 | 16777215
1193 |
1194 |
1195 |
1196 | QPushButton{
1197 | background-color:rgba(53, 132, 228,190);
1198 | border: none;
1199 | border-radius:10px;
1200 | color:white;
1201 | }
1202 |
1203 | QPushButton:hover{
1204 | background-color:rgb(32, 74, 135);
1205 | }
1206 |
1207 |
1208 | Reload Devices
1209 |
1210 |
1211 |
1212 | reload_btn.pngreload_btn.png
1213 |
1214 |
1215 | Ctrl+R
1216 |
1217 |
1218 |
1219 |
1220 |
1221 | 520
1222 | 250
1223 | 121
1224 | 31
1225 |
1226 |
1227 |
1228 |
1229 | 16777215
1230 | 16777215
1231 |
1232 |
1233 |
1234 | PointingHandCursor
1235 |
1236 |
1237 | QPushButton{
1238 | color:rgb(255,255,255);
1239 | background-color:rgba(53, 132, 228,190);
1240 | border: none;
1241 | border-radius:10px;
1242 | }
1243 |
1244 | QPushButton:hover{
1245 | background:rgb(32, 74, 135);
1246 | }
1247 |
1248 |
1249 | Start
1250 |
1251 |
1252 |
1253 | 60
1254 | 60
1255 |
1256 |
1257 |
1258 | Ctrl+Return
1259 |
1260 |
1261 |
1262 |
1263 |
1264 |
1265 |
1266 |
1267 | 10
1268 | 10
1269 | 151
1270 | 311
1271 |
1272 |
1273 |
1274 | QFrame{
1275 | background-color: rgb(22,22,22);
1276 | }
1277 |
1278 |
1279 | QFrame::StyledPanel
1280 |
1281 |
1282 | QFrame::Raised
1283 |
1284 |
1285 |
1286 |
1287 | 10
1288 | 10
1289 | 131
1290 | 291
1291 |
1292 |
1293 |
1294 | QLabel{
1295 | background-color: white;
1296 | }
1297 |
1298 |
1299 | Game Mode
1300 |
1301 |
1302 | Qt::AlignCenter
1303 |
1304 |
1305 |
1306 |
1307 |
1308 |
1309 | 180
1310 | 10
1311 | 661
1312 | 311
1313 |
1314 |
1315 |
1316 | QFrame{
1317 | color: rgb(255,255,255);
1318 | }
1319 |
1320 |
1321 | QFrame::StyledPanel
1322 |
1323 |
1324 | QFrame::Raised
1325 |
1326 |
1327 |
1328 |
1329 | 20
1330 | 20
1331 | 61
1332 | 41
1333 |
1334 |
1335 |
1336 | Device
1337 |
1338 |
1339 |
1340 |
1341 |
1342 | 80
1343 | 30
1344 | 571
1345 | 21
1346 |
1347 |
1348 |
1349 | QComboBox{
1350 | color:white;
1351 | border: none;
1352 | padding-top: 2px;
1353 | padding-bottom: 5px;
1354 | background-color:rgb(22, 22, 22);
1355 | border-radius:3px;
1356 | }
1357 |
1358 |
1359 |
1360 |
1361 |
1362 | 20
1363 | 70
1364 | 61
1365 | 51
1366 |
1367 |
1368 |
1369 | Bitrate
1370 |
1371 |
1372 |
1373 |
1374 |
1375 | 80
1376 | 80
1377 | 91
1378 | 26
1379 |
1380 |
1381 |
1382 | QLineEdit{
1383 | color:white;
1384 | border: none;
1385 | padding-top: 2px;
1386 | padding-bottom: 5px;
1387 | background-color:rgb(22, 22, 22);
1388 | border-radius:3px;
1389 | }
1390 |
1391 |
1392 | 3000000
1393 |
1394 |
1395 |
1396 |
1397 |
1398 | 180
1399 | 90
1400 | 41
1401 | 18
1402 |
1403 |
1404 |
1405 | Hz
1406 |
1407 |
1408 |
1409 |
1410 |
1411 | 220
1412 | 80
1413 | 141
1414 | 31
1415 |
1416 |
1417 |
1418 |
1419 | 8
1420 |
1421 |
1422 |
1423 | PointingHandCursor
1424 |
1425 |
1426 | QCheckBox{
1427 | color:white;
1428 | border: none;
1429 | padding-left:4px;
1430 | background-color:rgb(22, 22, 22);
1431 | border-radius:3px;
1432 | }
1433 | QCheckBox::indicator
1434 | {
1435 | border-radius: 0.25em;
1436 | border: 0.1em solid rgb(114, 159, 207);
1437 | }
1438 |
1439 | QCheckBox::indicator::checked
1440 | {
1441 | background-color:rgb(114, 159, 207);
1442 | }
1443 |
1444 |
1445 | Fullscreen
1446 |
1447 |
1448 | Ctrl+F
1449 |
1450 |
1451 |
1452 |
1453 |
1454 | 370
1455 | 80
1456 | 131
1457 | 31
1458 |
1459 |
1460 |
1461 |
1462 | 8
1463 |
1464 |
1465 |
1466 | PointingHandCursor
1467 |
1468 |
1469 | true
1470 |
1471 |
1472 | QCheckBox{
1473 | color:white;
1474 | border: none;
1475 | padding-left:4px;
1476 | background-color:rgb(22, 22, 22);
1477 | border-radius:3px;
1478 | }
1479 | QCheckBox::indicator
1480 | {
1481 | border-radius: 0.25em;
1482 | border: 0.1em solid rgb(114, 159, 207);
1483 | }
1484 |
1485 | QCheckBox::indicator::checked
1486 | {
1487 | background-color:rgb(114, 159, 207);
1488 | }
1489 |
1490 |
1491 | Borderless
1492 |
1493 |
1494 | Ctrl+B
1495 |
1496 |
1497 |
1498 |
1499 |
1500 | 20
1501 | 140
1502 | 121
1503 | 18
1504 |
1505 |
1506 |
1507 | Render Driver
1508 |
1509 |
1510 |
1511 |
1512 |
1513 | 120
1514 | 140
1515 | 531
1516 | 21
1517 |
1518 |
1519 |
1520 |
1521 | 0
1522 | 0
1523 |
1524 |
1525 |
1526 |
1527 | 16777215
1528 | 16777215
1529 |
1530 |
1531 |
1532 |
1533 | 8
1534 |
1535 |
1536 |
1537 | PointingHandCursor
1538 |
1539 |
1540 | QComboBox
1541 | {
1542 | color:white;
1543 | border: none;
1544 | padding-top: 2px;
1545 | padding-bottom: 5px;
1546 | background-color:rgb(22, 22, 22);
1547 | border-radius:3px;
1548 | }
1549 |
1550 | -
1551 |
1552 | opengl
1553 |
1554 |
1555 | -
1556 |
1557 | opengles
1558 |
1559 |
1560 | -
1561 |
1562 | opengles2
1563 |
1564 |
1565 | -
1566 |
1567 | direct3d
1568 |
1569 |
1570 | -
1571 |
1572 | metal
1573 |
1574 |
1575 | -
1576 |
1577 | software
1578 |
1579 |
1580 |
1581 |
1582 |
1583 |
1584 | 20
1585 | 180
1586 | 631
1587 | 41
1588 |
1589 |
1590 |
1591 | QLabel{
1592 | opacity: .5;
1593 | }
1594 |
1595 |
1596 | <html><head/><body><p><span style=" color:#ffff00;">* If you're using Windows, is recommended to use 'direct3d' render driver<br/>* In Game Mode, OTG tag is automatically launched with scrcpy args, to disable this, click "No OTG"</span></p></body></html>
1597 |
1598 |
1599 |
1600 |
1601 |
1602 | 20
1603 | 250
1604 | 141
1605 | 31
1606 |
1607 |
1608 |
1609 |
1610 | 16777215
1611 | 16777215
1612 |
1613 |
1614 |
1615 | QPushButton{
1616 | background-color:rgba(53, 132, 228,190);
1617 | border: none;
1618 | border-radius:10px;
1619 | color:white;
1620 | }
1621 |
1622 | QPushButton:hover{
1623 | background-color:rgb(32, 74, 135);
1624 | }
1625 |
1626 |
1627 | Reload Devices
1628 |
1629 |
1630 |
1631 | reload_btn.pngreload_btn.png
1632 |
1633 |
1634 | Ctrl+R
1635 |
1636 |
1637 |
1638 |
1639 |
1640 | 520
1641 | 250
1642 | 121
1643 | 31
1644 |
1645 |
1646 |
1647 |
1648 | 16777215
1649 | 16777215
1650 |
1651 |
1652 |
1653 | PointingHandCursor
1654 |
1655 |
1656 | QPushButton{
1657 | color:rgb(255,255,255);
1658 | background-color:rgba(53, 132, 228,190);
1659 | border: none;
1660 | border-radius:10px;
1661 | }
1662 |
1663 | QPushButton:hover{
1664 | background:rgb(32, 74, 135);
1665 | }
1666 |
1667 |
1668 | Start
1669 |
1670 |
1671 |
1672 | 60
1673 | 60
1674 |
1675 |
1676 |
1677 | Ctrl+Return
1678 |
1679 |
1680 |
1681 |
1682 |
1683 | 510
1684 | 80
1685 | 141
1686 | 31
1687 |
1688 |
1689 |
1690 |
1691 | 8
1692 |
1693 |
1694 |
1695 | PointingHandCursor
1696 |
1697 |
1698 | QCheckBox{
1699 | color:white;
1700 | border: none;
1701 | padding-left:4px;
1702 | background-color:rgb(22, 22, 22);
1703 | border-radius:3px;
1704 | }
1705 | QCheckBox::indicator
1706 | {
1707 | border-radius: 0.25em;
1708 | border: 0.1em solid rgb(114, 159, 207);
1709 | }
1710 |
1711 | QCheckBox::indicator::checked
1712 | {
1713 | background-color:rgb(114, 159, 207);
1714 | }
1715 |
1716 |
1717 | No OTG
1718 |
1719 |
1720 | Ctrl+F
1721 |
1722 |
1723 |
1724 |
1725 |
1726 |
1727 |
1728 |
1729 | 10
1730 | 10
1731 | 151
1732 | 311
1733 |
1734 |
1735 |
1736 | QFrame{
1737 | background-color: rgb(22,22,22);
1738 | }
1739 |
1740 |
1741 | QFrame::StyledPanel
1742 |
1743 |
1744 | QFrame::Raised
1745 |
1746 |
1747 |
1748 |
1749 | 10
1750 | 10
1751 | 131
1752 | 291
1753 |
1754 |
1755 |
1756 | QLabel{
1757 | background-color: white;
1758 | }
1759 |
1760 |
1761 | Manual
1762 |
1763 |
1764 | Qt::AlignCenter
1765 |
1766 |
1767 |
1768 |
1769 |
1770 |
1771 | 180
1772 | 10
1773 | 661
1774 | 311
1775 |
1776 |
1777 |
1778 | QFrame{
1779 | color: rgb(255,255,255);
1780 | }
1781 |
1782 |
1783 | QFrame::StyledPanel
1784 |
1785 |
1786 | QFrame::Raised
1787 |
1788 |
1789 |
1790 |
1791 | 20
1792 | 20
1793 | 61
1794 | 41
1795 |
1796 |
1797 |
1798 | Device
1799 |
1800 |
1801 |
1802 |
1803 |
1804 | 80
1805 | 30
1806 | 571
1807 | 21
1808 |
1809 |
1810 |
1811 | QComboBox{
1812 | color:white;
1813 | border: none;
1814 | padding-top: 2px;
1815 | padding-bottom: 5px;
1816 | background-color:rgb(22, 22, 22);
1817 | border-radius:3px;
1818 | }
1819 |
1820 |
1821 |
1822 |
1823 |
1824 | 20
1825 | 70
1826 | 61
1827 | 51
1828 |
1829 |
1830 |
1831 | Bitrate
1832 |
1833 |
1834 |
1835 |
1836 |
1837 | 80
1838 | 80
1839 | 91
1840 | 26
1841 |
1842 |
1843 |
1844 | QLineEdit{
1845 | color:white;
1846 | border: none;
1847 | padding-top: 2px;
1848 | padding-bottom: 5px;
1849 | background-color:rgb(22, 22, 22);
1850 | border-radius:3px;
1851 | }
1852 |
1853 |
1854 |
1855 |
1856 |
1857 |
1858 |
1859 |
1860 | 180
1861 | 90
1862 | 41
1863 | 18
1864 |
1865 |
1866 |
1867 | Hz
1868 |
1869 |
1870 |
1871 |
1872 |
1873 | 380
1874 | 80
1875 | 141
1876 | 31
1877 |
1878 |
1879 |
1880 |
1881 | 8
1882 |
1883 |
1884 |
1885 | PointingHandCursor
1886 |
1887 |
1888 | QCheckBox{
1889 | color:white;
1890 | border: none;
1891 | padding-left:4px;
1892 | background-color:rgb(22, 22, 22);
1893 | border-radius:3px;
1894 | }
1895 | QCheckBox::indicator
1896 | {
1897 | border-radius: 0.25em;
1898 | border: 0.1em solid rgb(114, 159, 207);
1899 | }
1900 |
1901 | QCheckBox::indicator::checked
1902 | {
1903 | background-color:rgb(114, 159, 207);
1904 | }
1905 |
1906 |
1907 | Fullscreen
1908 |
1909 |
1910 | Ctrl+F
1911 |
1912 |
1913 |
1914 |
1915 |
1916 | 220
1917 | 80
1918 | 151
1919 | 31
1920 |
1921 |
1922 |
1923 |
1924 | 8
1925 |
1926 |
1927 |
1928 | PointingHandCursor
1929 |
1930 |
1931 | true
1932 |
1933 |
1934 | QCheckBox{
1935 | color:white;
1936 | border: none;
1937 | padding-left:4px;
1938 | background-color:rgb(22, 22, 22);
1939 | border-radius:3px;
1940 | }
1941 | QCheckBox::indicator
1942 | {
1943 | border-radius: 0.25em;
1944 | border: 0.1em solid rgb(114, 159, 207);
1945 | }
1946 |
1947 | QCheckBox::indicator::checked
1948 | {
1949 | background-color:rgb(114, 159, 207);
1950 | }
1951 |
1952 |
1953 | View Only
1954 |
1955 |
1956 | Ctrl+X
1957 |
1958 |
1959 |
1960 |
1961 |
1962 | 530
1963 | 80
1964 | 121
1965 | 31
1966 |
1967 |
1968 |
1969 |
1970 | 8
1971 |
1972 |
1973 |
1974 | PointingHandCursor
1975 |
1976 |
1977 | true
1978 |
1979 |
1980 | QCheckBox{
1981 | color:white;
1982 | border: none;
1983 | padding-left:4px;
1984 | background-color:rgb(22, 22, 22);
1985 | border-radius:3px;
1986 | }
1987 | QCheckBox::indicator
1988 | {
1989 | border-radius: 0.25em;
1990 | border: 0.1em solid rgb(114, 159, 207);
1991 | }
1992 |
1993 | QCheckBox::indicator::checked
1994 | {
1995 | background-color:rgb(114, 159, 207);
1996 | }
1997 |
1998 |
1999 | Borderless
2000 |
2001 |
2002 | Ctrl+B
2003 |
2004 |
2005 |
2006 |
2007 |
2008 | 20
2009 | 140
2010 | 121
2011 | 18
2012 |
2013 |
2014 |
2015 | Render Driver
2016 |
2017 |
2018 |
2019 |
2020 |
2021 | 120
2022 | 140
2023 | 531
2024 | 21
2025 |
2026 |
2027 |
2028 |
2029 | 0
2030 | 0
2031 |
2032 |
2033 |
2034 |
2035 | 16777215
2036 | 16777215
2037 |
2038 |
2039 |
2040 |
2041 | 8
2042 |
2043 |
2044 |
2045 | PointingHandCursor
2046 |
2047 |
2048 | QComboBox
2049 | {
2050 | color:white;
2051 | border: none;
2052 | padding-top: 2px;
2053 | padding-bottom: 5px;
2054 | background-color:rgb(22, 22, 22);
2055 | border-radius:3px;
2056 | }
2057 |
2058 | -
2059 |
2060 | opengles2
2061 |
2062 |
2063 | -
2064 |
2065 | opengles
2066 |
2067 |
2068 | -
2069 |
2070 | opengl
2071 |
2072 |
2073 | -
2074 |
2075 | direct3d
2076 |
2077 |
2078 | -
2079 |
2080 | metal
2081 |
2082 |
2083 | -
2084 |
2085 | software
2086 |
2087 |
2088 |
2089 |
2090 |
2091 |
2092 | 20
2093 | 250
2094 | 141
2095 | 31
2096 |
2097 |
2098 |
2099 |
2100 | 16777215
2101 | 16777215
2102 |
2103 |
2104 |
2105 | QPushButton{
2106 | background-color:rgba(53, 132, 228,190);
2107 | border: none;
2108 | border-radius:10px;
2109 | color:white;
2110 | }
2111 |
2112 | QPushButton:hover{
2113 | background-color:rgb(32, 74, 135);
2114 | }
2115 |
2116 |
2117 | Reload Devices
2118 |
2119 |
2120 |
2121 | reload_btn.pngreload_btn.png
2122 |
2123 |
2124 | Ctrl+R
2125 |
2126 |
2127 |
2128 |
2129 |
2130 | 520
2131 | 250
2132 | 121
2133 | 31
2134 |
2135 |
2136 |
2137 |
2138 | 16777215
2139 | 16777215
2140 |
2141 |
2142 |
2143 | PointingHandCursor
2144 |
2145 |
2146 | QPushButton{
2147 | color:rgb(255,255,255);
2148 | background-color:rgba(53, 132, 228,190);
2149 | border: none;
2150 | border-radius:10px;
2151 | }
2152 |
2153 | QPushButton:hover{
2154 | background:rgb(32, 74, 135);
2155 | }
2156 |
2157 |
2158 | Start
2159 |
2160 |
2161 |
2162 | 60
2163 | 60
2164 |
2165 |
2166 |
2167 | Ctrl+Return
2168 |
2169 |
2170 |
2171 |
2172 |
2173 | 20
2174 | 180
2175 | 101
2176 | 21
2177 |
2178 |
2179 |
2180 | Additional args
2181 |
2182 |
2183 |
2184 |
2185 |
2186 | 120
2187 | 180
2188 | 521
2189 | 51
2190 |
2191 |
2192 |
2193 |
2194 | 10
2195 |
2196 |
2197 |
2198 | QTextEdit{
2199 | color:white;
2200 | border: none;
2201 | padding-top: 2px;
2202 | padding-bottom: 5px;
2203 | background-color:rgb(22, 22, 22);
2204 | border-radius:3px;
2205 | }
2206 |
2207 |
2208 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
2209 | <html><head><meta name="qrichtext" content="1" /><style type="text/css">
2210 | p, li { white-space: pre-wrap; }
2211 | </style></head><body style=" font-family:'Noto Sans, '; font-size:10pt; font-weight:400; font-style:normal;">
2212 | <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">--max-fps=60 </p></body></html>
2213 |
2214 |
2215 |
2216 |
2217 |
2218 |
2219 |
2220 |
2221 | 690
2222 | 10
2223 | 151
2224 | 311
2225 |
2226 |
2227 |
2228 | QFrame{
2229 | background-color: rgb(22,22,22);
2230 | }
2231 |
2232 |
2233 | QFrame::StyledPanel
2234 |
2235 |
2236 | QFrame::Raised
2237 |
2238 |
2239 |
2240 |
2241 | 10
2242 | 10
2243 | 131
2244 | 291
2245 |
2246 |
2247 |
2248 | QLabel{
2249 | background-color: white;
2250 | }
2251 |
2252 |
2253 | Configs
2254 |
2255 |
2256 | Qt::AlignCenter
2257 |
2258 |
2259 |
2260 |
2261 |
2262 |
2263 | 10
2264 | 10
2265 | 661
2266 | 311
2267 |
2268 |
2269 |
2270 | QFrame{
2271 | color: rgb(255,255,255);
2272 | }
2273 |
2274 |
2275 | QFrame::StyledPanel
2276 |
2277 |
2278 | QFrame::Raised
2279 |
2280 |
2281 |
2282 |
2283 | 140
2284 | 10
2285 | 351
2286 | 61
2287 |
2288 |
2289 |
2290 |
2291 | Cantarell
2292 | 11
2293 |
2294 |
2295 |
2296 | Configurations
2297 |
2298 |
2299 | Qt::AlignCenter
2300 |
2301 |
2302 |
2303 |
2304 |
2305 | 20
2306 | 60
2307 | 641
2308 | 121
2309 |
2310 |
2311 |
2312 | QFrame::Plain
2313 |
2314 |
2315 | <html><head/><body><p><span style=" font-weight:600;">Sorry :(</span></p><p>Configurations not implemented yet.</p><p>You can receive upcoming early access versions through Project's Github Page:</p><p><a href="https://github.com/hayukimori/scrcpy-pyqtgui/"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/hayukimori/scrcpy-pyqtgui/</span></a></p></body></html>
2316 |
2317 |
2318 | false
2319 |
2320 |
2321 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop
2322 |
2323 |
2324 | true
2325 |
2326 |
2327 | true
2328 |
2329 |
2330 |
2331 |
2332 |
2333 |
2334 |
2335 |
2336 | 110
2337 | 30
2338 | 711
2339 | 41
2340 |
2341 |
2342 |
2343 | QFrame{
2344 | background-color: rgba(28, 113, 216, 210)
2345 | }
2346 |
2347 |
2348 | QFrame::StyledPanel
2349 |
2350 |
2351 | QFrame::Raised
2352 |
2353 |
2354 | -
2355 |
2356 |
2357 |
2358 | Noto Sans Arabic Light
2359 | 11
2360 | 50
2361 | false
2362 |
2363 |
2364 |
2365 | QLabel{
2366 | background: none;
2367 | color: white;
2368 | }
2369 |
2370 |
2371 | Scrcpy PyQt5 GUI
2372 |
2373 |
2374 | Qt::AlignCenter
2375 |
2376 |
2377 |
2378 |
2379 |
2380 | stackedWidget
2381 | minimize_btn
2382 | exit_button
2383 | groupBox
2384 | frame_6
2385 |
2386 |
2387 |
2388 |
2389 |
2390 |
2391 |
2392 |
2393 |
--------------------------------------------------------------------------------