148 lines
5.2 KiB
Python
148 lines
5.2 KiB
Python
|
|
import sys
|
||
|
|
|
||
|
|
from pywinauto import backend
|
||
|
|
|
||
|
|
from PyQt5.QtCore import *
|
||
|
|
from PyQt5.QtGui import *
|
||
|
|
from PyQt5.QtWidgets import *
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
app = QApplication(sys.argv)
|
||
|
|
w = MyWindow()
|
||
|
|
w.show()
|
||
|
|
sys.exit(app.exec_())
|
||
|
|
|
||
|
|
|
||
|
|
class MyWindow(QWidget):
|
||
|
|
def __init__(self, *args):
|
||
|
|
QWidget.__init__(self, *args)
|
||
|
|
|
||
|
|
self.setFixedSize(930, 631)
|
||
|
|
self.setLocale(QLocale(QLocale.English, QLocale.UnitedStates))
|
||
|
|
self.setWindowTitle(QCoreApplication.translate("MainWindow", "PyInspect"))
|
||
|
|
|
||
|
|
self.central_widget = QWidget(self)
|
||
|
|
|
||
|
|
self.comboBox = QComboBox(self.central_widget)
|
||
|
|
self.comboBox.setGeometry(QRect(10, 10, 451, 22))
|
||
|
|
self.comboBox.setMouseTracking(False)
|
||
|
|
self.comboBox.setMaxVisibleItems(5)
|
||
|
|
self.comboBox.setObjectName("comboBox")
|
||
|
|
|
||
|
|
for _backend in backend.registry.backends.keys():
|
||
|
|
self.comboBox.addItem(_backend)
|
||
|
|
|
||
|
|
self.tree_view = QTreeView(self.central_widget)
|
||
|
|
self.tree_view.setGeometry(QRect(10, 40, 451, 581))
|
||
|
|
self.tree_view.setColumnWidth(0, 150)
|
||
|
|
|
||
|
|
self.comboBox.setCurrentText('uia')
|
||
|
|
self.__initialize_calc()
|
||
|
|
|
||
|
|
self.table_view = QTableView(self.central_widget)
|
||
|
|
self.table_view.setGeometry(QRect(470, 40, 451, 581))
|
||
|
|
|
||
|
|
self.comboBox.activated[str].connect(self.__show_tree)
|
||
|
|
|
||
|
|
def __initialize_calc(self, _backend='uia'):
|
||
|
|
self.element_info = backend.registry.backends[_backend].element_info_class()
|
||
|
|
self.tree_model = MyTreeModel(self.element_info, _backend)
|
||
|
|
self.tree_model.setHeaderData(0, Qt.Horizontal, 'Controls')
|
||
|
|
self.tree_view.setModel(self.tree_model)
|
||
|
|
self.tree_view.clicked.connect(self.__show_property)
|
||
|
|
|
||
|
|
def __show_tree(self, text):
|
||
|
|
backend = text
|
||
|
|
self.__initialize_calc(backend)
|
||
|
|
|
||
|
|
def __show_property(self, index=None):
|
||
|
|
data = index.data()
|
||
|
|
self.table_model = MyTableModel(self.tree_model.props_dict.get(data), self)
|
||
|
|
self.table_view.wordWrap()
|
||
|
|
self.table_view.setModel(self.table_model)
|
||
|
|
self.table_view.setColumnWidth(1, 320)
|
||
|
|
|
||
|
|
|
||
|
|
class MyTreeModel(QStandardItemModel):
|
||
|
|
def __init__(self, element_info, backend):
|
||
|
|
QStandardItemModel.__init__(self)
|
||
|
|
root_node = self.invisibleRootItem()
|
||
|
|
self.props_dict = {}
|
||
|
|
self.backend = backend
|
||
|
|
self.branch = QStandardItem(self.__node_name(element_info))
|
||
|
|
self.branch.setEditable(False)
|
||
|
|
root_node.appendRow(self.branch)
|
||
|
|
self.__generate_props_dict(element_info)
|
||
|
|
self.__get_next(element_info, self.branch)
|
||
|
|
|
||
|
|
def __get_next(self, element_info, parent):
|
||
|
|
for child in element_info.children():
|
||
|
|
self.__generate_props_dict(child)
|
||
|
|
child_item = QStandardItem(self.__node_name(child))
|
||
|
|
child_item.setEditable(False)
|
||
|
|
parent.appendRow(child_item)
|
||
|
|
self.__get_next(child, child_item)
|
||
|
|
|
||
|
|
def __node_name(self, element_info):
|
||
|
|
if 'uia' == self.backend:
|
||
|
|
return '%s "%s" (%s)' % (str(element_info.control_type), str(element_info.name), id(element_info))
|
||
|
|
return '"%s" (%s)' % (str(element_info.name), id(element_info))
|
||
|
|
|
||
|
|
def __generate_props_dict(self, element_info):
|
||
|
|
props = [
|
||
|
|
['control_id', str(element_info.control_id)],
|
||
|
|
['class_name', str(element_info.class_name)],
|
||
|
|
['enabled', str(element_info.enabled)],
|
||
|
|
['handle', str(element_info.handle)],
|
||
|
|
['name', str(element_info.name)],
|
||
|
|
['process_id', str(element_info.process_id)],
|
||
|
|
['rectangle', str(element_info.rectangle)],
|
||
|
|
['rich_text', str(element_info.rich_text)],
|
||
|
|
['visible', str(element_info.visible)]
|
||
|
|
]
|
||
|
|
|
||
|
|
props_win32 = [
|
||
|
|
] if (self.backend == 'win32') else []
|
||
|
|
|
||
|
|
props_uia = [
|
||
|
|
['control_type', str(element_info.control_type)],
|
||
|
|
['element', str(element_info.element)],
|
||
|
|
['framework_id', str(element_info.framework_id)],
|
||
|
|
['runtime_id', str(element_info.runtime_id)]
|
||
|
|
] if (self.backend == 'uia') else []
|
||
|
|
|
||
|
|
props.extend(props_uia)
|
||
|
|
props.extend(props_win32)
|
||
|
|
node_dict = {self.__node_name(element_info): props}
|
||
|
|
self.props_dict.update(node_dict)
|
||
|
|
|
||
|
|
|
||
|
|
class MyTableModel(QAbstractTableModel):
|
||
|
|
def __init__(self, datain, parent=None, *args):
|
||
|
|
QAbstractTableModel.__init__(self, parent, *args)
|
||
|
|
self.arraydata = datain
|
||
|
|
self.header_labels = ['Property', 'Value']
|
||
|
|
|
||
|
|
def rowCount(self, parent):
|
||
|
|
return len(self.arraydata)
|
||
|
|
|
||
|
|
def columnCount(self, parent):
|
||
|
|
return len(self.arraydata[0])
|
||
|
|
|
||
|
|
def data(self, index, role):
|
||
|
|
if not index.isValid():
|
||
|
|
return QVariant()
|
||
|
|
elif role != Qt.DisplayRole:
|
||
|
|
return QVariant()
|
||
|
|
return QVariant(self.arraydata[index.row()][index.column()])
|
||
|
|
|
||
|
|
def headerData(self, section, orientation, role=Qt.DisplayRole):
|
||
|
|
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
|
||
|
|
return self.header_labels[section]
|
||
|
|
return QAbstractTableModel.headerData(self, section, orientation, role)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|