Beispiel #1
0
# ---------------------------
# Treeにitemに子itemを追加する
# ---------------------------
import sys
from PySide2.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem

app = QApplication(sys.argv)

qw_tree = QTreeWidget()
qw_tree.setHeaderLabels(["name", "tel", "mail"])
qw_tree_parent_item = QTreeWidgetItem(['family'])
qw_tree_parent_item.addChild(
    QTreeWidgetItem(['A', '111-111-111', '*****@*****.**']))  # Itemに子Itemを追加
qw_tree.addTopLevelItem(qw_tree_parent_item)
qw_tree.expandAll()  # TreeのItemを全て開く
qw_tree.show()

sys.exit(app.exec_())
class QDecompilationOptions(QWidget):
    def __init__(self, code_view, instance, options=None, passes=None, peephole_opts=None):
        super().__init__()

        self._code_view = code_view
        self._instance = instance
        self._options = options
        self._opti_passes = passes
        self._peephole_opts = peephole_opts

        # widgets
        self._search_box = None  # type:QLineEdit
        self._treewidget = None  # type:QTreeWidget
        self._apply_btn = None  # type:QPushButton

        self._qoptions = [ ]
        self._qoptipasses = [ ]
        self._qpeephole_opts = [ ]

        self._init_widgets()

        self.reload()

    def reload(self, force=False):
        if force or self._options is None:
            self._options = self.get_default_options()

        if force or self._opti_passes is None:
            if not self._instance.project.am_none:
                self._opti_passes = self.get_all_passes()
            else:
                self._opti_passes = []

        if force or self._peephole_opts is None:
            self._peephole_opts = self.get_all_peephole_opts()

        self._reload_options()

    @property
    def selected_passes(self):
        selected = [ ]
        for item in self._qoptipasses:
            if item.checkState(0):
                selected.append(item.option)
        return selected

    @property
    def selected_peephole_opts(self):
        selected = []
        for item in self._qpeephole_opts:
            if item.checkState(0):
                selected.append(item.option)
        return selected

    @property
    def option_and_values(self):
        ov = [ ]
        for item in self._qoptions:
            if item.checkState(0):
                ov.append((item.option, True))
            else:
                ov.append((item.option, False))
        return ov

    @property
    def options(self):
        return self._options

    @options.setter
    def options(self, v):
        self._options = v
        self._reload_options()

    def get_default_options(self):
        return dec_options

    def get_default_passes(self):
        if self._instance is None or self._instance.project.am_none:
            return set()
        return get_default_optimization_passes(self._instance.project.arch, self._instance.project.simos.name)

    def get_all_passes(self):
        return get_optimization_passes(self._instance.project.arch, self._instance.project.simos.name)

    def get_default_peephole_opts(self):
        return STMT_OPTS + EXPR_OPTS

    def get_all_peephole_opts(self):
        return STMT_OPTS + EXPR_OPTS

    def _init_widgets(self):

        # search box
        self._search_box = QLineEdit()

        # tree view
        self._treewidget = QTreeWidget()
        self._treewidget.setHeaderHidden(True)

        # refresh button
        self._apply_btn = QPushButton("Apply")
        self._apply_btn.clicked.connect(self._code_view.decompile)

        layout = QVBoxLayout()
        layout.addWidget(self._search_box)
        layout.addWidget(self._treewidget)
        layout.addWidget(self._apply_btn)

        self.setLayout(layout)

    def _reload_options(self):

        self._treewidget.clear()
        self._qoptions.clear()
        self._qoptipasses.clear()
        self._qpeephole_opts.clear()

        categories = { }

        # populate the tree widget with new options
        for option in sorted(self._options, key=lambda x: x.name):
            if option.category in categories:
                category = categories[option.category]
            else:
                category = QTreeWidgetItem(self._treewidget, [option.category])

            w = QDecompilationOption(category, option, OptionType.OPTION, enabled=option.default_value==True)
            self._qoptions.append(w)

        passes_category = QTreeWidgetItem(self._treewidget, ["Optimization Passes"])
        categories['passes'] = passes_category

        default_passes = set(self.get_default_passes())
        for pass_ in self._opti_passes:
            w = QDecompilationOption(passes_category, pass_, OptionType.OPTIMIZATION_PASS,
                                     enabled=pass_ in default_passes)
            self._qoptipasses.append(w)

        po_category = QTreeWidgetItem(self._treewidget, ["Peephole Optimizations"])
        categories['peephole_opts'] = po_category

        default_peephole_opts = self.get_default_peephole_opts()
        for opt_ in self._peephole_opts:
            w = QDecompilationOption(po_category, opt_, OptionType.PEEPHOLE_OPTIMIZATION,
                                     enabled=opt_ in default_peephole_opts)
            self._qpeephole_opts.append(w)

        # expand all
        self._treewidget.expandAll()
Beispiel #3
0
import sys
from PySide2.QtWidgets import QApplication, QTreeWidget, QTreeWidgetItem

app = QApplication(sys.argv)

qw_tree = QTreeWidget()
qw_tree.setHeaderLabels(["name", "tel", "mail"])

qw_tree_parent_item_1 = QTreeWidgetItem(['family'])
qw_tree_parent_item_1.addChild(QTreeWidgetItem(['A', '111-111-111', '*****@*****.**']))
qw_tree_parent_item_1.addChild(QTreeWidgetItem(['B', '222-222-222', '*****@*****.**']))

qw_tree_parent_item_2 = QTreeWidgetItem(['school'])
qw_tree_parent_item_2.addChild(QTreeWidgetItem(['C', '333-333-333', '*****@*****.**']))
qw_tree_parent_item_2.addChild(QTreeWidgetItem(['D', '444-444-444', '*****@*****.**']))

qw_tree.addTopLevelItem(qw_tree_parent_item_1)
qw_tree.addTopLevelItem(qw_tree_parent_item_2)
qw_tree.expandAll()
qw_tree.show()

sys.exit(app.exec_())
Beispiel #4
0
class TraceWindow(QMainWindow):
    def __init__(self, qmp):

        QMainWindow.__init__(self)

        self.qmp = qmp

        os.system('rm /tmp/errors.log 2>/dev/null')

        self.trace_events = self.qmp.hmp_command('info trace-events')
        self.qmp.hmp_command('logfile /tmp/errors.log')

        self.trace_events = sorted(
            self.trace_events['return'].split('\r\n'))[1:]
        self.activated = []

        self.length = 100

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.disp_output)
        self.timer.start(100)

        self.init_ui()

    def init_ui(self):

        self.setWindowTitle('Trace Event Window')
        self.setGeometry(100, 100, 800, 600)

        bar = self.menuBar()

        file_ = bar.addMenu('File')
        export_log = QAction('Save to File',
                             self,
                             triggered=lambda: self.save_log())

        options = bar.addMenu('Options')
        auto_refresh = QAction(
            'Auto Refresh',
            self,
            checkable=True,
            triggered=lambda: self.timer.start(100)
            if auto_refresh.isChecked() else self.timer.stop())
        auto_refresh.setChecked(True)

        options.addAction(auto_refresh)
        file_.addAction(export_log)

        vgrid = QVBoxLayout()
        grid = QHBoxLayout()

        self.tree = QTreeWidget()
        self.tree.setHeaderLabels(['Name'])

        self.top = []
        self.lst = []

        for n, event in enumerate(self.trace_events):
            word = event.split('_')[0]
            if word not in self.top:
                self.top.append(word)
                item = QTreeWidgetItem(self.tree)
                self.lst.append(item)
                item.setText(0, word)
            subitem = QTreeWidgetItem(item)
            subitem.setText(0, '    ' + event.split(' : ')[0])
            # subitem.setCheckState(0, Qt.Unchecked)
            cbox = QCheckBox()
            cbox.stateChanged.connect(lambda state, text=subitem.text(0): self.
                                      handle_checked(state, text))
            self.tree.setItemWidget(subitem, 0, cbox)

        # self.tree.setColumnWidth(0, 25)

        self.tracelist = QLabel()
        self.disp_output()

        self.traceview = QScrollArea()
        self.traceview.setWidget(self.tracelist)
        self.traceview.setWidgetResizable(True)

        search = QHBoxLayout()

        self.search_bar = QLineEdit(self)

        self.completer = QCompleter(self.top, self)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)

        self.search_bar.setCompleter(self.completer)

        search_button = QPushButton('Search')
        search_button.clicked.connect(lambda: self.tree.setCurrentItem(
            self.lst[self.top.index(self.search_bar.text())]))

        expand = QPushButton('▼')
        expand.setFixedSize(QSize(25, 25))
        expand.clicked.connect(lambda: self.tree.expandAll())

        collapse = QPushButton('▲')
        collapse.setFixedSize(QSize(25, 25))
        collapse.clicked.connect(lambda: self.tree.collapseAll())

        self.search_bar.returnPressed.connect(lambda: search_button.click())

        search.addWidget(self.search_bar)
        search.addWidget(search_button)
        search.addWidget(expand)
        search.addWidget(collapse)

        self.digest = QLabel()

        vgrid.addLayout(search)
        vgrid.addWidget(self.tree)

        vgridwid = QWidget()
        vgridwid.setLayout(vgrid)

        split = QSplitter(Qt.Horizontal)

        split.addWidget(vgridwid)
        split.addWidget(self.traceview)

        split.setStretchFactor(1, 1)

        # grid.addLayout(vgrid)
        grid.addWidget(split)
        # grid.addWidget(self.tracelist)

        self.disp_output()

        center = QWidget()
        center.setLayout(grid)
        self.setCentralWidget(center)
        self.show()

    def disp_output(self):

        self.shorten_file()

        with open('/tmp/errors.log', 'r') as errors:

            self.digest = []
            lines = 0

            for line in errors:
                if re.match(r"\d+@\d+\.\d+:.*", line):
                    self.digest.append(line)
                    lines += 1

            if not self.digest:
                self.digest = ['<font color="grey">Empty...</font>']

            self.digest = ''.join(self.digest[-self.length:])

            self.tracelist.setText(self.digest)
            self.tracelist.setFont(QFont('Monospace', 10))
            self.tracelist.setTextInteractionFlags(Qt.TextSelectableByMouse)

    def shorten_file(self):

        with open('/tmp/errors.log', 'r+') as tracefile:

            content = ''.join(tracefile.readlines()[-(self.length * 3):])

            tracefile.seek(0)
            tracefile.truncate()

            tracefile.write(content)

    def save_log(self):

        name = QFileDialog.getSaveFileName(self, 'Save File', '',
                                           'Text files (*.txt)')

        log_file = open(name[0], 'w')
        log_file.write(self.digest)
        log_file.close()

    def handle_checked(self, state, text):

        if state:
            self.qmp.hmp_command('trace-event %s on' % text.strip())
            self.activated.append(text)
        else:
            self.qmp.hmp_command('trace-event %s off' % text.strip())
            self.activated.remove(text)

    def closeEvent(self, event):

        self.timer.stop()

        for e in self.activated:
            self.qmp.hmp_command('trace-event %s off' % e.strip())

        os.system('rm /tmp/errors.log')

        event.accept()
class QDecompilationOptions(QWidget):
    def __init__(self, code_view, instance, options=None, passes=None, peephole_opts=None):
        super().__init__()

        self.dirty = True

        self._code_view = code_view
        self._instance = instance
        self._options = options
        self._opti_passes = passes
        self._peephole_opts = peephole_opts

        # widgets
        self._search_box = None  # type:QLineEdit
        self._treewidget = None  # type:QTreeWidget
        self._apply_btn = None  # type:QPushButton

        self._qoptions = [ ]
        self._qoptipasses = [ ]
        self._qpeephole_opts = [ ]

        self._init_widgets()

        self.reload()

    def reload(self, force=False):
        if force or self._options is None:
            self._options = self.get_default_options()

        if force or self._opti_passes is None:
            if not self._instance.project.am_none:
                self._opti_passes = self.get_all_passes()
            else:
                self._opti_passes = []

        if force or self._peephole_opts is None:
            self._peephole_opts = self.get_all_peephole_opts()

        self._reload_options()

    def _on_item_changed(self, item, _column):
        if getattr(item.option, 'clears_cache', True):
            self.dirty = True

    def _on_apply_pressed(self):
        if self.dirty:
            self.dirty = False
            # clear the cached version
            self._code_view.decompile(reset_cache=True)
        else:
            self._code_view.codegen.reapply_options(self.option_and_values)
            self._code_view.codegen.am_event()

    @property
    def selected_passes(self):
        selected = [ ]
        for item in self._qoptipasses:
            if item.checkState(0):
                selected.append(item.option)
        return selected

    @property
    def selected_peephole_opts(self):
        selected = []
        for item in self._qpeephole_opts:
            if item.checkState(0):
                selected.append(item.option)
        return selected

    @property
    def option_and_values(self):
        ov = [ ]
        for item in self._qoptions:
            if item.checkState(0):
                ov.append((item.option, True))
            else:
                ov.append((item.option, False))
        return ov

    @property
    def options(self):
        return self._options

    @options.setter
    def options(self, v):
        self._options = v
        self._reload_options()

    def get_default_options(self):  # pylint: disable=no-self-use
        return dec_options

    def get_default_passes(self):
        if self._instance is None or self._instance.project.am_none:
            return set()
        return get_default_optimization_passes(self._instance.project.arch, self._instance.project.simos.name)

    def get_all_passes(self):
        return get_optimization_passes(self._instance.project.arch, self._instance.project.simos.name)

    def get_default_peephole_opts(self):  # pylint: disable=no-self-use
        return STMT_OPTS + EXPR_OPTS

    def get_all_peephole_opts(self):  # pylint: disable=no-self-use
        return STMT_OPTS + EXPR_OPTS

    def _init_widgets(self):

        # search box
        self._search_box = QLineEdit()
        self._search_box.textChanged.connect(self._on_search_box_text_changed)

        # tree view
        self._treewidget = QTreeWidget()
        self._treewidget.setHeaderHidden(True)
        self._treewidget.itemChanged.connect(self._on_item_changed)

        # refresh button
        self._apply_btn = QPushButton("Apply")
        self._apply_btn.clicked.connect(self._on_apply_pressed)

        layout = QVBoxLayout()
        layout.addWidget(self._search_box)
        layout.addWidget(self._treewidget)
        layout.addWidget(self._apply_btn)

        self.setLayout(layout)

    def _reload_options(self, filter_by: Optional[str]=None):

        self._treewidget.clear()
        self._qoptions.clear()
        self._qoptipasses.clear()
        self._qpeephole_opts.clear()

        categories = { }

        if filter_by:
            filter_by = filter_by.lower()

        # populate the tree widget with new options
        for option in sorted(self._options, key=lambda x: x.NAME):
            if filter_by and not (filter_by in option.NAME.lower() or filter_by in option.category.lower()):
                continue
            if option.category in categories:
                category = categories[option.category]
            else:
                category = QTreeWidgetItem(self._treewidget, [option.category])
                categories[option.category] = category

            w = QDecompilationOption(category, option, OptionType.OPTION, enabled=option.default_value)
            self._qoptions.append(w)

        passes_category = QTreeWidgetItem(self._treewidget, ["Optimization Passes"])
        categories['passes'] = passes_category

        default_passes = set(self.get_default_passes())
        for pass_ in self._opti_passes:
            if filter_by and not (filter_by in pass_.__name__.lower() or filter_by in pass_.NAME.lower()):
                continue
            w = QDecompilationOption(passes_category, pass_, OptionType.OPTIMIZATION_PASS,
                                     enabled=pass_ in default_passes)
            self._qoptipasses.append(w)

        po_category = QTreeWidgetItem(self._treewidget, ["Peephole Optimizations"])
        categories['peephole_opts'] = po_category

        default_peephole_opts = self.get_default_peephole_opts()
        for opt_ in self._peephole_opts:
            if filter_by and not (filter_by in opt_.NAME.lower() or filter_by in opt_.DESCRIPTION.lower()):
                continue
            w = QDecompilationOption(po_category, opt_, OptionType.PEEPHOLE_OPTIMIZATION,
                                     enabled=opt_ in default_peephole_opts)
            self._qpeephole_opts.append(w)

        # expand all
        self._treewidget.expandAll()

    def _on_search_box_text_changed(self, text: str):
        self._reload_options(filter_by=text)