def gui_layout(self): main_layout = QHBoxLayout() layout1 = QVBoxLayout() right_layout = QHBoxLayout() toolbox = ToolBox() layout1.addWidget(toolbox) layout1.addWidget(Color('pink')) layout1.addWidget(Color('blue')) main_layout.setContentsMargins(0, 0, 0, 0) main_layout.setSpacing(0) main_layout.addLayout(layout1) table = TabWidget() main_layout.addWidget(table) right_layout.addWidget(self.right_up_text_edit()) right_layout.addWidget(self.right_down_text_edit()) main_layout.addLayout(right_layout) widget = QWidget() widget.setLayout(main_layout) self.setCentralWidget(widget)
def __init__(self, parent=None): """Initialize Window with basic properties.""" super(Window, self).__init__(parent) self.setWindowTitle(project_name) self.setWindowIcon(QIcon('logo.png')) self.statusBar().showMessage('') menu = self.menuBar() # File menu file_menu = menu.addMenu('&File') menus = [ ('&New query', 'Ctrl+N', self.open_new_tab, False), ('&Save query', 'Ctrl+S', self.save_query_to_file, False), ('&Open query', 'Ctrl+O', self.open_query_from_file, False), ] for cmd_name, shortcut, connected_func, separator in menus: action = QAction(cmd_name, self) if shortcut: action.setShortcut(shortcut) action.triggered.connect(connected_func) file_menu.addAction(action) if separator: file_menu.addSeparator() # TOC menu toc_menu = menu.addMenu('&Schemas') toc_hide_action = QAction('&Hide/show panel', self) toc_hide_action.setShortcuts(QKeySequence('F1')) toc_hide_action.triggered.connect(self._do_toc_hide_show) toc_expand_action = QAction('&Expand all', self) toc_expand_action.triggered.connect(self.toc_expand_all) toc_collapse_action = QAction('&Collapse all', self) toc_collapse_action.triggered.connect(self.toc_collapse_all) toc_menu.addAction(toc_hide_action) toc_menu.addAction(toc_expand_action) toc_menu.addAction(toc_collapse_action) # Result menu result_menu = menu.addMenu('&Result') result_export_menu = result_menu.addMenu('Export to') result_export_menu.setToolTipsVisible(True) export_action_qgis = result_export_menu.addAction('&QGIS') export_action_qgis.setToolTip( 'Get plain WKT to use with the QuickWKT plugin') export_action_arc = result_export_menu.addAction('&ArcMap') export_action_arc.setToolTip( 'Get arcpy code to create in_memory layer') export_action_df = result_export_menu.addAction('&DataFrame') export_action_df.setToolTip( 'Get Python code to create a pandas df using a temp csv file') export_action_md = result_export_menu.addAction('&Markdown') export_action_md.setToolTip('Get table formatted in Markdown') option = None export_action_qgis.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_qgis.text())) export_action_arc.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_arc.text())) export_action_df.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_df.text())) export_action_md.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_md.text())) settings_menu = menu.addMenu('&Settings') settings_menu.setToolTipsVisible(True) self.do_include_geometry = QAction( 'Include geometry column in query result set', self, checkable=True) self.do_include_geometry.setToolTip( """Will include WKT representation of geometry column in the result table""") settings_menu.addAction(self.do_include_geometry) self.do_include_geometry.setChecked(True) self.tab_widget = TabWidget() self.setCentralWidget(self.tab_widget) self.setGeometry(100, 100, 1000, 900) self.show() self.export_result_window = None return
class Window(QMainWindow): """Window that contains the tab container.""" # ---------------------------------------------------------------------- def __init__(self, parent=None): """Initialize Window with basic properties.""" super(Window, self).__init__(parent) self.setWindowTitle(project_name) self.setWindowIcon(QIcon('logo.png')) self.statusBar().showMessage('') menu = self.menuBar() # File menu file_menu = menu.addMenu('&File') menus = [ ('&New query', 'Ctrl+N', self.open_new_tab, False), ('&Save query', 'Ctrl+S', self.save_query_to_file, False), ('&Open query', 'Ctrl+O', self.open_query_from_file, False), ] for cmd_name, shortcut, connected_func, separator in menus: action = QAction(cmd_name, self) if shortcut: action.setShortcut(shortcut) action.triggered.connect(connected_func) file_menu.addAction(action) if separator: file_menu.addSeparator() # TOC menu toc_menu = menu.addMenu('&Schemas') toc_hide_action = QAction('&Hide/show panel', self) toc_hide_action.setShortcuts(QKeySequence('F1')) toc_hide_action.triggered.connect(self._do_toc_hide_show) toc_expand_action = QAction('&Expand all', self) toc_expand_action.triggered.connect(self.toc_expand_all) toc_collapse_action = QAction('&Collapse all', self) toc_collapse_action.triggered.connect(self.toc_collapse_all) toc_menu.addAction(toc_hide_action) toc_menu.addAction(toc_expand_action) toc_menu.addAction(toc_collapse_action) # Result menu result_menu = menu.addMenu('&Result') result_export_menu = result_menu.addMenu('Export to') result_export_menu.setToolTipsVisible(True) export_action_qgis = result_export_menu.addAction('&QGIS') export_action_qgis.setToolTip( 'Get plain WKT to use with the QuickWKT plugin') export_action_arc = result_export_menu.addAction('&ArcMap') export_action_arc.setToolTip( 'Get arcpy code to create in_memory layer') export_action_df = result_export_menu.addAction('&DataFrame') export_action_df.setToolTip( 'Get Python code to create a pandas df using a temp csv file') export_action_md = result_export_menu.addAction('&Markdown') export_action_md.setToolTip('Get table formatted in Markdown') option = None export_action_qgis.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_qgis.text())) export_action_arc.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_arc.text())) export_action_df.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_df.text())) export_action_md.triggered.connect( lambda evt, arg=option: self.export_result( evt, export_action_md.text())) settings_menu = menu.addMenu('&Settings') settings_menu.setToolTipsVisible(True) self.do_include_geometry = QAction( 'Include geometry column in query result set', self, checkable=True) self.do_include_geometry.setToolTip( """Will include WKT representation of geometry column in the result table""") settings_menu.addAction(self.do_include_geometry) self.do_include_geometry.setChecked(True) self.tab_widget = TabWidget() self.setCentralWidget(self.tab_widget) self.setGeometry(100, 100, 1000, 900) self.show() self.export_result_window = None return # ---------------------------------------------------------------------- def export_result(self, evt, option): """Export result set into an output format.""" current_tab = self.tab_widget.widget(self.tab_widget.currentIndex()) try: if not test_mode: if not current_tab.table.table_data.rowCount(): raise else: if not current_tab.table.table_data.number_layer_rows: raise except BaseException: return QApplication.setOverrideCursor(Qt.WaitCursor) df = current_tab.table.get_selected_data_as_df() if not self.export_result_window: self.export_result_window = ExportResultWindow() if option == '&QGIS': if self.window().tab_widget.currentWidget( ).geometry_isin_query and self.window( ).do_include_geometry.isChecked(): s = '\n'.join(df[df.columns[-1]].tolist()) self.export_result_window.result.setText(s) else: self.export_result_window.result.setText('') if option == '&ArcMap': if self.window().tab_widget.currentWidget( ).geometry_isin_query and self.window( ).do_include_geometry.isChecked(): # TODO: get the fields data along with the geometries/dump csv snippet = self._get_arcmap_snippet( geoms=df[df.columns[-1]].tolist()) self.export_result_window.result.setText(snippet) else: self.export_result_window.result.setText('') if option == '&DataFrame': out_csv = os.path.join(tempfile.gettempdir(), 'data.csv') df.to_csv(out_csv, sep=';') s = '{0}{1}'.format( 'import pandas as pd\n', 'df = pd.read_csv(r"{out_csv}", sep=";", index_col=0)'.format( out_csv=out_csv)) self.export_result_window.result.setText(s) if option == '&Markdown': if not tabulate_found: self.export_result_window.result.setText( 'Tabulate package is not installed.\n' 'Get it from https://pypi.python.org/pypi/tabulate') else: s = tabulate(df, headers='keys', tablefmt='pipe', floatfmt='.4f') if len(df) > 1000: out_md = os.path.join(tempfile.gettempdir(), 'data.md') with io.open(out_md, 'w', encoding='utf-8') as f: f.write(s) self.export_result_window.result.setText( 'Markdown file is saved at {0}'.format(out_md)) else: self.export_result_window.result.setText(s) QApplication.restoreOverrideCursor() self.export_result_window.show() return # ---------------------------------------------------------------------- def open_new_tab(self): """Open a new query tab.""" self.tab_widget.add_tab_page() return # ---------------------------------------------------------------------- def save_query_to_file(self): """Save query of the focused tab.""" current_tab = self.tab_widget.widget(self.tab_widget.currentIndex()) if current_tab: tab_text = current_tab.query.document().toPlainText() if tab_text: name = QFileDialog.getSaveFileName(self, 'Save as new file', filter='All Files (*)') if name[0]: with io.open(name[0], 'w', encoding='utf-8') as f: f.write(tab_text) f.close() return # ---------------------------------------------------------------------- def open_query_from_file(self): """Open text file with query into the focused tab.""" name = QFileDialog.getOpenFileName(self, 'Open a query text file', filter='All Files (*)') if name[0]: with io.open(name[0], 'r', encoding='utf-8') as f: query = f.readlines() f.close() self.open_new_tab() current_tab = self.tab_widget.widget( self.tab_widget.currentIndex()) current_tab.query.document().setPlainText(''.join(query)) return # ---------------------------------------------------------------------- def toc_expand_all(self): """Expand all items in the schemas panel.""" try: self.tab_widget.currentWidget().toc.expandAll() except BaseException: return # ---------------------------------------------------------------------- def toc_collapse_all(self): """Collapse all items in the schemas panel.""" try: self.tab_widget.currentWidget().toc.collapseAll() except BaseException: return # ---------------------------------------------------------------------- def _do_toc_hide_show(self): """Hide or show toc panel.""" try: self.tab_widget.currentWidget()._do_toc_hide_show() except BaseException: pass # ---------------------------------------------------------------------- def _get_arcmap_snippet(self, geoms): """Get arcpy code with received table rows ready to load into ArcMap.""" gp_call = "arcpy.CopyFeatures_management(geoms,'in_memory\GDBeeLayer')" base_string = '{geoms}{for_loop}{build_geom}{append_geom}{copy_feats}' snippet = base_string.format( geoms='geoms = []\n', for_loop='for wkt_str in {0}:\n'.format(geoms), build_geom='\tg = arcpy.FromWKT(wkt_str)\n', append_geom='\tgeoms.append(g)\n', copy_feats=gp_call, ) return snippet
from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication from PyQt5.QtWidgets import QLabel, QVBoxLayout, QTextEdit, QAction from tab_widget import TabWidget class TextEdit(QTextEdit): def __init__(self, i,parent=None): super(TextEdit, self).__init__(parent) action = QAction('test', self) action.setShortcut('ctrl+d') action.setShortcutContext(Qt.WidgetWithChildrenShortcut) action.triggered.connect(lambda : print('test', i)) self.addAction(action) if __name__ == '__main__': import sys app = QApplication(sys.argv) tab_widget = TabWidget() tab_widget.addTab(TextEdit(1), 'Onglet Test 1') tab_widget.addTab(TextEdit(2), 'Onglet Test 2') tab_widget.addTab(TextEdit(3), 'Onglet Test 3') tab_widget.show() app.exec_()
def initUI(self): self.tab_w = TabWidget(self) self.setCentralWidget(self.tab_w) self.show()
def _init_widgets(self): self.tab_editor_widget = TabWidget(self) self.code_editors_widgets = []
class MainWindow(QtGui.QMainWindow): WINDOW_WIDTH = 800 WINDOW_HEIGHT = 600 WINDOW_TITLE = 'Synesthesia' CODE_EDITOR_FONT = QtGui.QFont('Consolas', 11) def __init__(self): super(MainWindow, self).__init__(); self._init_icons() self._init_window_properties() self._init_actions() self._init_widgets() self._init_menubar() self._init_toolbar() self._init_layout() def _init_window_properties(self): self.setGeometry(50, 50, self.WINDOW_WIDTH, self.WINDOW_HEIGHT) self.setWindowIcon(self.icon_python) self.setWindowTitle(self.WINDOW_TITLE) self.statusBar() def _init_icons(self): self.icon_open = QtGui.QIcon('images/open_22.png') self.icon_save = QtGui.QIcon('images/save_22.png') self.icon_run_analysis = QtGui.QIcon('images/run_analysis_22.png') self.icon_clear_coverage = QtGui.QIcon('images/clear_22.png') self.icon_refresh = QtGui.QIcon('images/refresh_22.png') self.icon_zoom = QtGui.QIcon('images/zoom_22.png') self.icon_python = QtGui.QIcon('images/python-icon.svg') def _init_actions(self): self.action_exit = QtGui.QAction('Exit', self) self.action_exit.setStatusTip('Exit application') self.action_exit.triggered.connect(QtGui.qApp.quit) self.action_open_file = QtGui.QAction(self.icon_open, 'Open File...', self) self.action_open_file.setStatusTip('Open Python source file') self.action_open_file.triggered.connect(self.open_file) self.action_save_file = QtGui.QAction(self.icon_save, 'Save File', self) self.action_save_file.setStatusTip('Save changes to the File') self.action_save_file.setShortcut('Ctrl+S') self.action_save_file.triggered.connect(self.save_file) self.action_run_analysis = QtGui.QAction(self.icon_run_analysis, 'Run Analysis', self) self.action_run_analysis.setStatusTip('Run statistical analysis') self.action_run_analysis.triggered.connect(self.run_analysis) self.action_clear_coverage = QtGui.QAction(self.icon_clear_coverage, 'Clear Coverage', self) self.action_clear_coverage.setStatusTip('Clear the colored coverage') self.action_clear_coverage.triggered.connect(self.clear_coverage) self.action_show_about_dialog = QtGui.QAction('About Synesthesia', self) self.action_show_about_dialog.triggered.connect(self.show_about_dialog) self.action_refresh_definitions = QtGui.QAction(self.icon_refresh, 'Reload Definitions', self) self.action_refresh_definitions.setStatusTip('Reload method and input lists definitions of currently opened file') self.action_refresh_definitions.triggered.connect(self.load_definitions) self.action_toggle_zoom = QtGui.QAction(self.icon_zoom, 'Toggle Zoom / Dezoom', self) self.action_toggle_zoom.setStatusTip('Toggle between zoomed and dezoomed view.') self.action_toggle_zoom.triggered.connect(self.toggle_zoom) def _init_widgets(self): self.tab_editor_widget = TabWidget(self) self.code_editors_widgets = [] def _init_menubar(self): file_menu = self.menuBar().addMenu('File') file_menu.addAction(self.action_open_file) file_menu.addAction(self.action_save_file) file_menu.addAction(self.action_exit) debug_menu = self.menuBar().addMenu('Debug') debug_menu.addAction(self.action_run_analysis) debug_menu.addAction(self.action_clear_coverage) debug_menu.addAction(self.action_refresh_definitions) debug_menu.addAction(self.action_toggle_zoom) help_menu = self.menuBar().addMenu('Help') help_menu.addAction(self.action_show_about_dialog) def _init_toolbar(self): self.toolbar = self.addToolBar('Shortcuts') self.toolbar.setFloatable(False) self.toolbar.setMovable(False) self.toolbar.addAction(self.action_open_file) self.toolbar.addAction(self.action_save_file) self.toolbar.addAction(self.action_run_analysis) self.toolbar.addAction(self.action_clear_coverage) self.toolbar.addAction(self.action_refresh_definitions) self.toolbar.addAction(self.action_toggle_zoom) def _init_layout(self): layout = QtGui.QGridLayout() layout.setSpacing(0) layout.setMargin(0) layout.addWidget(self.tab_editor_widget, 1, 0, 1, 4) self.right_widget = QtGui.QWidget() rightLayout = QtGui.QVBoxLayout() self.module_label = QtGui.QLabel() self.func_combobox = QtGui.QComboBox() self.testFunc_combobox = QtGui.QComboBox() self.input_combobox = QtGui.QComboBox() self.passed_input_label = QtGui.QLabel() self.failed_input_label = QtGui.QLabel() self.result_label = QtGui.QLabel("Results:") self.result_label.setVisible(False) rightLayout.addWidget(QtGui.QLabel('Module:')) rightLayout.addWidget(self.module_label) rightLayout.addWidget(QtGui.QLabel('Function to be analyzed:')) rightLayout.addWidget(self.func_combobox) rightLayout.addWidget(QtGui.QLabel('Test Function:')) rightLayout.addWidget(self.testFunc_combobox) rightLayout.addWidget(QtGui.QLabel('Input List:')) rightLayout.addWidget(self.input_combobox) rightLayout.addWidget(self.result_label) rightLayout.addWidget(self.passed_input_label) rightLayout.addWidget(self.failed_input_label) rightLayout.addStretch(2) self.right_widget.setLayout(rightLayout) layout.addWidget(self.right_widget,1,4) central_widget = QtGui.QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) def open_file(self): file_name = QtGui.QFileDialog.getOpenFileName(self, caption='Open file', filter='Python files (*.py);;All files (*)') if file_name != '': self.load_file(unicode(file_name.toUtf8(), encoding="utf-8")) def load_file(self, file_name): # Clear all opened files. self.code_editors_widgets = [] self.tab_editor_widget.remove_all_tabs() # Create new code editor in new tab code_editor = CodeWidget(self, file_name, self.CODE_EDITOR_FONT) self.code_editors_widgets.append(code_editor) self.tab_editor_widget.add_new_tab(code_editor) # Load file in new code editor file_ = open(file_name, 'r') code_editor.setPlainText(file_.read()) file_.close() # Load method and input list definition self.load_definitions() def load_definitions(self): # Stop if no file is currently open if self.tab_editor_widget.currentWidget() is None: return # Clear all combo boxes self.func_combobox.clear() self.testFunc_combobox.clear() self.input_combobox.clear() # Find all method and lists in the opened file. module_name = self.tab_editor_widget.currentWidget().filename sys.path.append(os.path.dirname(module_name)) buggy_module = imp.load_source(os.path.basename(module_name)[:-3], module_name) name_list = dir(buggy_module) func_names = get_func_names(buggy_module, name_list) list_names = get_list_names(buggy_module, name_list) sys.path.pop() # Set the current module to the current tab self.module_name = module_name self.module_label.setText('-> ' + os.path.basename(module_name)) self.result_label.setVisible(False) self.passed_input_label.setText("") self.failed_input_label.setText("") # Add the found method / list names to the combo boxes self.func_combobox.addItems(func_names) self.testFunc_combobox.addItems(func_names) self.input_combobox.addItems(list_names) def save_file(self): code_editor = self.tab_editor_widget.currentWidget() if code_editor is None: return file_ = open(code_editor.filename, 'w') file_.write(code_editor.toPlainText()) file_.close() code_editor.document().setModified(False) def run_analysis(self): # The following hack forces Python to reload all opened modules for code_editor in self.code_editors_widgets: module_name = os.path.basename(code_editor.filename)[:-3] imp.load_source(module_name, code_editor.filename) if self.tab_editor_widget.currentWidget() is not None: analyser = StatisticalAnalyser() module_name = self.module_name method_name = str(self.func_combobox.currentText()) test_name = str(self.testFunc_combobox.currentText()) inputs_name = str(self.input_combobox.currentText()) analyser.statistical_debug(module_name, method_name, test_name, inputs_name) if analyser.isTestFuncCorrect: successes, fails = analyser.get_input_statistics() self.result_label.setVisible(True) self.passed_input_label.setText("Number of Passed Inputs: "+str(successes)) self.failed_input_label.setText("Number of Failed Inputs: "+str(fails)) line_phi = analyser.get_line_phi() self.display_coverage(line_phi) else: QtGui.QMessageBox.warning(self, 'Warning', 'Please provide a correct test function!', QtGui.QMessageBox.Ok) else: QtGui.QMessageBox.warning(self, 'Warning', 'No code to analyze. Please load a python file!', QtGui.QMessageBox.Ok) def display_coverage(self, coverage): self.clear_coverage() for filename in coverage: if self.tab_editor_widget.get_widget(filename) is None: code_editor = CodeWidget(self, filename, self.CODE_EDITOR_FONT) self.code_editors_widgets.append(code_editor) file_ = open(filename, 'r') code_editor.setPlainText(file_.read()) file_.close() code_editor.show() self.tab_editor_widget.add_new_tab(code_editor) else: code_editor = self.tab_editor_widget.get_widget(filename) for line in coverage[filename]: phi = coverage[filename][line] if not phi == 'NaN': code_editor.color_line(line, green_red_percentile(phi * 50 + 50)) else: code_editor.color_line(line, QtGui.QColor(200, 200, 200, 127)) def clear_coverage(self): for code_editor in self.code_editors_widgets: code_editor.clear_line_coloring() def toggle_zoom(self): current_editor = self.tab_editor_widget.currentWidget() if current_editor is not None: current_editor.toggle_zoom() def show_about_dialog(self): about_text = 'Synesthesia\nPython statistical debugger\n\nNisa Bozkurt\nBayram Kiran\nKevin Salvesen' QtGui.QMessageBox.about(self, 'About Synesthesia', about_text)
def initUI(self): self.tab_w = TabWidget(self) self.setCentralWidget(self.tab_w) self.setGeometry(0, 0, 1000, 1000) self.show()