class MainUI(QtWidgets.QMainWindow): def __init__(self): super(MainUI, self).__init__() self.resize(960, 540) self.setFont(QFont("Microsoft YaHei")) self.main_widget = QWidget() self.main_layout = QHBoxLayout(self.main_widget) self.main_layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) self.setCentralWidget(self.main_widget) # ----------------------设置窗口标题---------------------- self.setWindowTitle("test") # 设置窗口名 # ----------------------设备栏---------------------- self.devices_chose_list = foldWidget() # type: foldWidget # self.init_devices_list() # 初始化device_list # self.main_layout.addWidget(self.devices_chose_list) # ----------------------设备功能栏---------------------- self.device_widget = QWidget(objectName='device_tool_widget') # device_widget设置为水平布局 self.device_layout = QHBoxLayout(self.device_widget) self.device_layout.setObjectName('deviceLayout') self.device_layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) # device_widget添加到主布局 self.main_layout.addWidget(self.device_widget) # ----------------设备信息_常用操作界面----------------- # 将设备信息界与设备常用功能界面,放置在一个水平布局中. self.device_info_tool_widget = QWidget( objectName='deviceInfoAndToolWidegt') self.device_info_tool_layout = QHBoxLayout( self.device_info_tool_widget) self.device_info_tool_layout.setObjectName('deviceInfoAndToolLayout') self.device_info_tool_layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft) self.device_layout.addWidget(self.device_info_tool_widget) # ----------------------设备选择按钮---------------------- self.device_chose_widget = QWidget(objectName='deviceChoseWidget') self.device_chose_layout = QVBoxLayout(self.device_chose_widget) self.device_chose_layout.setObjectName('deviceChoseLayout') self.device_info_tool_layout.addWidget(self.device_chose_widget) self.device_chose_widget.setMinimumSize(QSize(230, 390)) self.device_chose_widget.setMaximumSize(QSize(230, 390)) self.device_chose = deviceChoseWidget() self.device_chose_layout.addWidget(self.device_chose) self.device_chose.setMinimumSize(QSize(220, 75)) self.device_chose.setMaximumSize(QSize(220, 75)) # ----------------------设备信息界面---------------------- self.device_info_widget = deviceInfoWidget() # type: deviceInfoWidget self.device_info_widget.setObjectName('deviceInfoWidget') self.device_chose_layout.addWidget(self.device_info_widget) self.device_info_widget.setMinimumSize(QSize(220, 300)) self.device_info_widget.setMaximumSize(QSize(220, 300)) # ----------------------常用工具界面---------------------- self.device_tool_widget = deviceToolWidget() self.device_info_tool_layout.addWidget(self.device_tool_widget) self.device_tool_widget.setMinimumSize(QSize(500, 380)) self.device_tool_widget.setMaximumSize(QSize(500, 380)) # ----------------------主界面--------------------------- # self.device_chose_widget.setStyleSheet('background-color: rgb(85, 170, 0);') self.selected_device = None self.devices_list = DeviceList() # 设置回调函数 self.devices_list_thread = None self.device_info_thread = None # self.init_devices_list_loop() self.init_install_app_hook() # self.init_device_info_hook() def init_devices_list_loop(self): def callback(): def fun(): while True: devices = ADBDevice().devices if devices: return devices return fun self.devices_list_thread = LoopThread(hook=callback(), delay=2) self.devices_list_thread.connect(self.update_devices_list) self.devices_list_thread.start() def update_devices_list(self, deviceList: dict): # print(';'.join([f'{device_id}:{state}' for device_id, state in deviceList.items()])) # Step1: 检查已经加入的设备是否还在线 for device_id in self.devices_list: if not self.devices_list.get_device_status_by_id(device_id): logger.info(f'设备 {device_id} 已离线') # Step2: 未加入的设备创建绑定按钮,添加到devices_chose_list中 for device_id, state in deviceList.items(): if state == 'device' and device_id not in self.devices_list: device, item, button = self.create_device_btn(device_id) self.devices_chose_list.add_button(item, button) self.devices_list.add_device(device) logger.info(f'添加设备: {device_id} ') def create_device_btn( self, device_id: str) -> Tuple[ADBDevice, QListWidgetItem, CustomButton]: device = ADBDevice(device_id) item = QListWidgetItem(self.devices_chose_list) button = CustomButton(text=device_id, parent=self.devices_chose_list) def callback(adb: ADBDevice): def fun(): logger.info(f'选中设备: {adb.device_id}') self.selected_device = adb return fun button.set_click_hook(callback(adb=device)) return device, item, button def init_device_info_hook(self): def callback(cls): def fun(): while True: device = cls.selected_device if not device: return None logger.info( f'更新设备信息, device={device}, id={device.device_id}') return cls._get_device_info(device) return fun self.device_info_thread = LoopThread(hook=callback(cls=self), delay=2) self.device_info_thread.connect(self.update_device_info) self.device_info_thread.start() @staticmethod def _get_device_info(device: ADBDevice): displayInfo = device.getPhysicalDisplayInfo() width, height = displayInfo['width'], displayInfo['height'] return { 'serialno': device.device_id, 'model': device.model, 'manufacturer': device.manufacturer, 'memory': device.memory, 'displaySize': f'{width}x{height}', 'android_version': device.abi_version, 'sdk_version': device.sdk_version, } def update_device_info(self, deviceInfo): if isinstance(deviceInfo, dict): device_info_widget = self.device_info_widget device_info_widget.update_label('serialno', deviceInfo['serialno']) device_info_widget.update_label('model', deviceInfo['model']) device_info_widget.update_label('manufacturer', deviceInfo['manufacturer']) device_info_widget.update_label('memory', deviceInfo['memory']) device_info_widget.update_label('displaySize', deviceInfo['displaySize']) device_info_widget.update_label('android_version', deviceInfo['android_version']) device_info_widget.update_label('sdk_version', deviceInfo['sdk_version']) def init_install_app_hook(self): install_widget = self.device_tool_widget.install_app install_widget.update_thread = Thread() def callback(cls): def fun(): device = cls.selected_device # type: ADBDevice path = cls.get_install_app_path() print(f"安装应用={path or None}") if path: install_widget.setEnabled(False) try: device.install(local=path) except Exception as e: return AdbInstallError(f'应用安装失败\n{e}') finally: install_widget.setEnabled(True) return fun install_widget.update_thread.add_hook(callback(cls=self)) install_widget.set_btn_hook(install_widget.update_thread.start) install_widget.update_thread.connect(self.raise_dialog) def get_install_app_path(self): """ 从控件中获取安装应用的路径 """ path = self.device_tool_widget.install_app.getText() return path def raise_dialog(self, exceptions): if isinstance(exceptions, AdbBaseError): dialog = InfoDialog(text='错误', infomativeText=str(exceptions), parent=self) dialog.open()