예제 #1
0
 def define_shortcuts(self):
     QtGui.QShortcut(
         QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_Plus), self,
         self.zoom_in)
     QtGui.QShortcut(
         QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_Minus),
         self,
         self.zoom_out,
     )
예제 #2
0
    def __init__(self, parent=None):
        super(AList, self).__init__(parent)

        # BAD: inline - twiggers twice
        QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Delete), self,
                  self.remove_selected)

        # Good: twiggers once
        shortcut = QShortcut(self)
        shortcut.setKey(QtGui.QKeySequence(QtCore.Qt.Key_D))
        shortcut.activated.connect(self.remove_selected)
예제 #3
0
파일: hello.py 프로젝트: zxc-steve/pyqt
    def __init__(self, *args):
        QtWidgets.QFileDialog.__init__(self, *args)
        self.setOption(self.DontUseNativeDialog, True)
        #self.setFileMode(self.DirectoryOnly)
        self.setFileMode(QtWidgets.QFileDialog.Directory)

        for view in self.findChildren(QtWidgets.QListView):
            if isinstance(view.model(), QtWidgets.QFileSystemModel):
                view.setSelectionMode(
                    QtWidgets.QAbstractItemView.ExtendedSelection)

        #https://stackoverflow.com/questions/28544425/pyqt-qfiledialog-multiple-directory-selection
        # this is for ExtendedSelection, not for comboBox enter event
        for view in self.findChildren(QtWidgets.QTreeView):
            if isinstance(view.model(), QtWidgets.QFileSystemModel):
                view.setSelectionMode(
                    QtWidgets.QAbstractItemView.ExtendedSelection)

        combo_box = self.findChild(QtWidgets.QComboBox, "lookInCombo")
        print(combo_box)
        combo_box.setEditable(True)

        #https://stackoverflow.com/questions/51189055/qcombobox-using-enter-event
        shortcut = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return),
                                   combo_box,
                                   activated=self.onActivated)
예제 #4
0
    def addShortcut(self, shortcut, slotMethod, *args):
        """Add a shortcut to a slot (event handler)

        Args:
            shortcut (STRING): Something like 'ALT+m'
            slotMethod (STRING): Method of GuiSlots 'Slot' class

        Returns:
            object: QShortcut object
        """

        # gui_slot converts to:
        # self.parent.slots.slotMethod(*args)
        gui_slot = getattr(self.parent.slots, slotMethod)

        sc = QtGui.QShortcut(QtGui.QKeySequence(shortcut), self.parent)

        # connect shortcut to slot
        # e.g. self.parent.slots.toggleLogDock(*args)
        sc.activated.connect(lambda: gui_slot(*args))

        return
예제 #5
0
    def setup_menu(self):
        self.file_menu = self.w.menuBar().addMenu("&File")
        self.file_menu_actions = []

        newAct = qtg.QAction('&New')
        newAct.setShortcut(qtg.QKeySequence.New)
        newAct.setStatusTip('Create a new Design')
        newAct.triggered.connect(self.clearWindow)
        self.file_menu.addAction(newAct)
        self.file_menu_actions.append(newAct)

        openAct = qtg.QAction('&Open')
        openAct.setShortcut(qtg.QKeySequence.Open)
        openAct.setStatusTip('Open an existing Design Plan')
        openAct.triggered.connect(self.open_plan)
        self.file_menu.addAction(openAct)
        self.file_menu_actions.append(openAct)

        saveAct = qtg.QAction('&Save Plan')
        saveAct.setShortcut(qtg.QKeySequence.Save)
        saveAct.setStatusTip('Save the Design Plan')
        saveAct.triggered.connect(lambda: self.save_plan(False))
        self.file_menu.addAction(saveAct)
        self.file_menu_actions.append(saveAct)

        saveAsAct = qtg.QAction('Save Plan &As')
        saveAsAct.setShortcut(qtg.QKeySequence.SaveAs)
        saveAsAct.setStatusTip('Save the Design Plan As')
        saveAsAct.triggered.connect(lambda: self.save_plan(True))
        self.file_menu.addAction(saveAsAct)
        self.file_menu_actions.append(saveAsAct)

        svgAct = qtg.QAction('&Export Image')
        svgAct.setShortcut(qtg.QKeySequence(qtc.Qt.CTRL | qtc.Qt.Key_E))
        svgAct.setStatusTip('Save the implementation Image')
        svgAct.triggered.connect(self.saveSvg)
        self.file_menu.addAction(svgAct)
        self.file_menu_actions.append(svgAct)

        quitAct = qtg.QAction('&Quit')
        quitAct.setShortcut(qtg.QKeySequence(qtc.Qt.CTRL | qtc.Qt.Key_Q))
        quitAct.setStatusTip('Quit the application')
        quitAct.triggered.connect(self.quit)  # TODO prompt for save
        self.file_menu.addAction(quitAct)
        self.file_menu_actions.append(quitAct)

        self.edit_menu = self.w.menuBar().addMenu("&Edit")
        self.edit_menu_actions = []

        recipeAct = qtg.QAction('Enabled &Recipes')
        recipeAct.setStatusTip('Edit the Enabled Recipes')
        recipeAct.triggered.connect(self.recipe_window.show)
        self.edit_menu.addAction(recipeAct)
        self.edit_menu_actions.append(recipeAct)

        self.distAct = qtg.QAction('&Distribute Machines')
        self.distAct.setStatusTip(
            'Show a recipe quantity distributed across an integer number of machines'
        )
        self.distAct.setCheckable(True)
        self.distAct.triggered.connect(self.go_fn)
        self.edit_menu.addAction(self.distAct)
        self.edit_menu_actions.append(self.distAct)

        excessAct = qtg.QAction('Remove &Excess')
        excessAct.setStatusTip('Remove excess Inputs from Plan')
        excessAct.triggered.connect(self.remove_excess_inputs)
        self.edit_menu.addAction(excessAct)
        self.edit_menu_actions.append(excessAct)
예제 #6
0
    def __init__(self, args):
        super().__init__(args)
        self.game_data = game_parse.get_docs()
        self.item_lookup = {
            item.display: item
            for item in self.game_data.items.values()
        }

        self.solution = None
        self.current_file = None
        self.windows = []

        self.w = qtw.QMainWindow()
        self.central_widget = qtw.QWidget()
        self.w.setCentralWidget(self.central_widget)
        self.w.setWindowTitle("Satisfactory Solver")
        self.w.resize(900, 600)

        self.center_layout = qtw.QHBoxLayout()
        self.central_widget.setLayout(self.center_layout)

        self.input_layout = qtw.QVBoxLayout()
        self.center_layout.addLayout(self.input_layout)

        self.input_search_box = ItemSearchWidget(
            'Add Input', self.item_lookup,
            qtg.QShortcut(qtg.QKeySequence(qtc.Qt.CTRL | qtc.Qt.Key_I),
                          self.w))
        self.input_layout.addWidget(self.input_search_box)

        self.input_scroll = qtw.QScrollArea()
        self.input_scroll.setWidgetResizable(True)
        self.input_scroll.setHorizontalScrollBarPolicy(
            qtc.Qt.ScrollBarAlwaysOff)
        self.input_layout.addWidget(self.input_scroll)

        self.input_scroll_holdee = WidthAnchor(self.input_scroll)
        self.input_scroll.setFocusProxy(self.input_scroll_holdee)
        self.input_list = qtw.QVBoxLayout(self.input_scroll_holdee)
        self.input_scroll_holdee.setLayout(self.input_list)
        self.input_list.insertStretch(-1)
        self.input_list.setSpacing(0)
        self.input_scroll.setWidget(self.input_scroll_holdee)

        self.input_search_box.callback = self.add_input

        self.output_search = ItemSearchWidget(
            'Set Target', self.item_lookup,
            qtg.QShortcut(qtg.QKeySequence(qtc.Qt.CTRL | qtc.Qt.Key_T),
                          self.w))
        self.input_layout.addWidget(self.output_search)
        self.go_box = qtw.QPushButton("Go!")
        self.output_show_box = SchematicInputWidget(None, self.go_box,
                                                    self.open_recipe_window,
                                                    self.game_data, False)
        self.output_show_box.setIcon(OUTPUT_ICON)
        self.input_layout.addWidget(self.output_show_box)

        self.output_search.callback = self.output_show_box.setItem

        self.svg_scene = qtw.QGraphicsScene()
        self.svg_view = ZoomingGraphicsView(self.svg_scene)
        self.svg_item = qtsvgw.QGraphicsSvgItem()
        self.svg_renderer = qtsvg.QSvgRenderer()
        self.svg_item.setSharedRenderer(self.svg_renderer)
        self.svg_scene.addItem(self.svg_item)

        self.center_layout.addWidget(self.svg_view, 1)

        self.go_box.clicked.connect(self.go_fn)
        self.go_box.setShortcut(qtg.QKeySequence(qtc.Qt.CTRL | qtc.Qt.Key_G))

        self.recipe_window = AlternateRecipeWindow(self.game_data)

        self.set_tab_order()

        self.setup_menu()

        if len(args) > 1:
            self.current_file = args[1]
            self.open_plan(True)
예제 #7
0
 def textEffectMenu(self):
     format = self.currentCharFormat()
     font = format.font()
     menu = QtWidgets.QMenu("Text Effect")
     formatting = (
         (
             "&Bold",
             "Ctrl+B",
             RichTextLineEdit.Bold,
             self.fontWeight() > QtGui.QFont.Normal,
         ),
         ("&Italic", "Ctrl+I", RichTextLineEdit.Italic, self.fontItalic()),
         ("Strike &out", None, RichTextLineEdit.StrikeOut,
          format.fontStrikeOut()),
         ("&Underline", "Ctrl+U", RichTextLineEdit.Underline,
          self.fontUnderline()),
         (
             "&Monospaced",
             None,
             RichTextLineEdit.Monospaced,
             font.family() == self.monofamily,
         ),
         (
             "&Serifed",
             None,
             RichTextLineEdit.Serif,
             font.family() == self.seriffamily,
         ),
         (
             "S&ans Serif",
             None,
             RichTextLineEdit.Sans,
             font.family() == self.sansfamily,
         ),
         (
             "&No super or subscript",
             None,
             RichTextLineEdit.NoSuperOrSubscript,
             format.verticalAlignment() ==
             QtGui.QTextCharFormat.AlignNormal,
         ),
         (
             "Su&perscript",
             None,
             RichTextLineEdit.Superscript,
             format.verticalAlignment() ==
             QtGui.QTextCharFormat.AlignSuperScript,
         ),
         (
             "Subs&cript",
             None,
             RichTextLineEdit.Subscript,
             format.verticalAlignment() ==
             QtGui.QTextCharFormat.AlignSubScript,
         ),
     )
     for text, shortcut, data, checked in formatting:
         action = menu.addAction(text, self.setTextEffect)
         if shortcut is not None:
             action.setShortcut(QtGui.QKeySequence(shortcut))
         action.setData(data)
         action.setCheckable(True)
         action.setChecked(checked)
     self.ensureCursorVisible()
     menu.exec(self.viewport().mapToGlobal(self.cursorRect().center()))
예제 #8
0
    def menu(self):
        menubar = QMenuBar(self)

        #--------------
        file_menu = menubar.addMenu('File')

        # open_act = QtGui.QAction('Open', self, checkable=True)
        # open_act = QtGui.QAction('Open', self)
        # open_act.triggered.connect(self.open_as_cb)
        file_menu.addAction("New (template)", self.new_model_cb,
                            QtGui.QKeySequence('Ctrl+n'))
        file_menu.addAction("Open", self.open_as_cb,
                            QtGui.QKeySequence('Ctrl+o'))
        file_menu.addAction("Save", self.save_cb, QtGui.QKeySequence('Ctrl+s'))
        # recent_act = QtGui.QAction('Recent', self)
        # save_act = QtGui.QAction('Save', self)
        # save_act.triggered.connect(self.save_cb)
        # saveas_act = QtGui.QAction('Save As my.xml', self)

        # file_menu.setStatusTip('enable/disable Dark mode')
        # new_model_act = QtGui.QAction('', self)
        # file_menu.addAction(new_model_act)
        # new_model_act.triggered.connect(self.new_model_cb)

        #--------------
        samples_menu = file_menu.addMenu("Samples (copy of)")
        biorobots_act = QtGui.QAction('biorobots', self)
        samples_menu.addAction(biorobots_act)
        biorobots_act.triggered.connect(self.biorobots_cb)

        cancer_biorobots_act = QtGui.QAction('cancer biorobots', self)
        samples_menu.addAction(cancer_biorobots_act)
        cancer_biorobots_act.triggered.connect(self.cancer_biorobots_cb)

        hetero_act = QtGui.QAction('heterogeneity', self)
        samples_menu.addAction(hetero_act)
        hetero_act.triggered.connect(self.hetero_cb)

        pred_prey_act = QtGui.QAction('predator-prey-farmer', self)
        samples_menu.addAction(pred_prey_act)
        pred_prey_act.triggered.connect(self.pred_prey_cb)

        virus_mac_act = QtGui.QAction('virus-macrophage', self)
        samples_menu.addAction(virus_mac_act)
        virus_mac_act.triggered.connect(self.virus_mac_cb)

        worm_act = QtGui.QAction('worm', self)
        samples_menu.addAction(worm_act)
        worm_act.triggered.connect(self.worm_cb)

        cancer_immune_act = QtGui.QAction('cancer immune (3D)', self)
        samples_menu.addAction(cancer_immune_act)
        cancer_immune_act.triggered.connect(self.cancer_immune_cb)

        template_act = QtGui.QAction('template', self)
        samples_menu.addAction(template_act)
        template_act.triggered.connect(self.template_cb)

        subcell_act = QtGui.QAction('subcellular', self)
        samples_menu.addAction(subcell_act)
        subcell_act.triggered.connect(self.subcell_cb)

        #--------------
        # file_menu.addAction(open_act)
        # file_menu.addAction(recent_act)
        # file_menu.addAction(save_act)
        # file_menu.addAction(save_act, self.save_act, QtGui.QKeySequence("Ctrl+s"))
        # file_menu.addAction(saveas_act)

        #--------------
        self.models_menu = menubar.addMenu('Models')
        models_menu_act = QtGui.QAction('-----', self)
        self.models_menu.addAction(models_menu_act)
        models_menu_act.triggered.connect(self.select_current_model_cb)
        # self.models_menu.addAction('Load sample', self.select_current_model_cb)

        #--------------
        tools_menu = menubar.addMenu('Tools')
        tools_menu_act = QtGui.QAction('Validate', self)
        tools_menu.addAction(tools_menu_act)
예제 #9
0
    def init_menu(self):
        menubar = self.menuBar()
        menubar.setNativeMenuBar(False)

        file_menu = menubar.addMenu(t("File"))

        setting_action = QAction(
            self.si(QtWidgets.QStyle.SP_FileDialogListView), t("Settings"),
            self)
        setting_action.setShortcut("Ctrl+S")
        setting_action.triggered.connect(self.show_setting)

        exit_action = QAction(self.si(QtWidgets.QStyle.SP_DialogCancelButton),
                              t("Exit"), self)
        exit_action.setShortcut(QtGui.QKeySequence("Ctrl+Q"))
        exit_action.setStatusTip(t("Exit application"))
        exit_action.triggered.connect(self.close)

        file_menu.addAction(setting_action)
        file_menu.addSeparator()
        file_menu.addAction(exit_action)

        profile_menu = menubar.addMenu(t("Profiles"))
        new_profile_action = QAction(t("New Profile"), self)
        new_profile_action.triggered.connect(self.new_profile)

        show_profile_action = QAction(t("Current Profile Settings"), self)
        show_profile_action.triggered.connect(self.show_profile)

        delete_profile_action = QAction(t("Delete Current Profile"), self)
        delete_profile_action.triggered.connect(self.delete_profile)
        profile_menu.addAction(new_profile_action)
        profile_menu.addAction(show_profile_action)
        profile_menu.addAction(delete_profile_action)

        tools_menu = menubar.addMenu(t("Tools"))
        concat_action = QAction(
            QtGui.QIcon(get_icon("onyx-queue",
                                 self.app.fastflix.config.theme)),
            t("Concatenation Builder"), self)
        concat_action.triggered.connect(self.show_concat)
        tools_menu.addAction(concat_action)

        wiki_action = QAction(self.si(QtWidgets.QStyle.SP_FileDialogInfoView),
                              t("FastFlix Wiki"), self)
        wiki_action.triggered.connect(self.show_wiki)

        about_action = QAction(self.si(QtWidgets.QStyle.SP_FileDialogInfoView),
                               t("About"), self)
        about_action.triggered.connect(self.show_about)

        changes_action = QAction(
            self.si(QtWidgets.QStyle.SP_FileDialogDetailedView),
            t("View Changes"), self)
        changes_action.triggered.connect(self.show_changes)

        log_dir_action = QAction(self.si(QtWidgets.QStyle.SP_DialogOpenButton),
                                 t("Open Log Directory"), self)
        log_dir_action.triggered.connect(self.show_log_dir)

        log_action = QAction(
            self.si(QtWidgets.QStyle.SP_FileDialogDetailedView),
            t("View GUI Debug Logs"), self)
        log_action.triggered.connect(self.show_logs)

        report_action = QAction(self.si(QtWidgets.QStyle.SP_DialogHelpButton),
                                t("Report Issue"), self)
        report_action.triggered.connect(self.open_issues)

        version_action = QAction(self.si(QtWidgets.QStyle.SP_BrowserReload),
                                 t("Check for Newer Version of FastFlix"),
                                 self)
        version_action.triggered.connect(
            lambda: latest_fastflix(no_new_dialog=True))

        ffmpeg_update_action = QAction(self.si(QtWidgets.QStyle.SP_ArrowDown),
                                       t("Download Newest FFmpeg"), self)
        ffmpeg_update_action.triggered.connect(self.download_ffmpeg)

        clean_logs_action = QAction(
            self.si(QtWidgets.QStyle.SP_DialogResetButton),
            t("Clean Old Logs"), self)
        clean_logs_action.triggered.connect(self.clean_old_logs)

        help_menu = menubar.addMenu(t("Help"))
        help_menu.addAction(wiki_action)
        help_menu.addSeparator()
        help_menu.addAction(changes_action)
        help_menu.addAction(report_action)
        help_menu.addAction(log_dir_action)
        help_menu.addAction(log_action)
        help_menu.addAction(clean_logs_action)
        help_menu.addSeparator()
        help_menu.addAction(version_action)
        if reusables.win_based:
            help_menu.addAction(ffmpeg_update_action)
        help_menu.addSeparator()
        help_menu.addAction(about_action)
예제 #10
0
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)

        quit = QtWidgets.QPushButton("&Quit")
        quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold))

        self.connect(quit, QtCore.SIGNAL("clicked()"), qApp,
                     QtCore.SLOT("quit()"))

        angle = LCDRange("ANGLE")
        angle.setRange(5, 70)

        force = LCDRange("FORCE")
        force.setRange(10, 50)

        cannonBox = QtWidgets.QFrame()
        cannonBox.setFrameStyle(QtWidgets.QFrame.WinPanel
                                | QtWidgets.QFrame.Sunken)

        self.cannonField = CannonField()

        self.connect(angle, QtCore.SIGNAL("valueChanged(int)"),
                     self.cannonField.setAngle)
        self.connect(self.cannonField, QtCore.SIGNAL("angleChanged(int)"),
                     angle.setValue)

        self.connect(force, QtCore.SIGNAL("valueChanged(int)"),
                     self.cannonField.setForce)
        self.connect(self.cannonField, QtCore.SIGNAL("forceChanged(int)"),
                     force.setValue)

        self.connect(self.cannonField, QtCore.SIGNAL("hit()"), self.hit)
        self.connect(self.cannonField, QtCore.SIGNAL("missed()"), self.missed)

        shoot = QtWidgets.QPushButton("&Shoot")
        shoot.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold))

        self.connect(shoot, QtCore.SIGNAL("clicked()"), self.fire)
        self.connect(self.cannonField, QtCore.SIGNAL("canShoot(bool)"), shoot,
                     QtCore.SLOT("setEnabled(bool)"))

        restart = QtWidgets.QPushButton("&New Game")
        restart.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold))

        self.connect(restart, QtCore.SIGNAL("clicked()"), self.newGame)

        self.hits = QtWidgets.QLCDNumber(2)
        self.shotsLeft = QtWidgets.QLCDNumber(2)
        hitsLabel = QtWidgets.QLabel("HITS")
        shotsLeftLabel = QtWidgets.QLabel("SHOTS LEFT")

        QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Enter), self,
                        self.fire)
        QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return), self,
                        self.fire)
        QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_Q),
                        self, QtCore.SLOT("close()"))

        topLayout = QtWidgets.QHBoxLayout()
        topLayout.addWidget(shoot)
        topLayout.addWidget(self.hits)
        topLayout.addWidget(hitsLabel)
        topLayout.addWidget(self.shotsLeft)
        topLayout.addWidget(shotsLeftLabel)
        topLayout.addStretch(1)
        topLayout.addWidget(restart)

        leftLayout = QtWidgets.QVBoxLayout()
        leftLayout.addWidget(angle)
        leftLayout.addWidget(force)

        cannonLayout = QtWidgets.QVBoxLayout()
        cannonLayout.addWidget(self.cannonField)
        cannonBox.setLayout(cannonLayout)

        gridLayout = QtWidgets.QGridLayout()
        gridLayout.addWidget(quit, 0, 0)
        gridLayout.addLayout(topLayout, 0, 1)
        gridLayout.addLayout(leftLayout, 1, 0)
        gridLayout.addWidget(cannonBox, 1, 1, 2, 1)
        gridLayout.setColumnStretch(1, 10)
        self.setLayout(gridLayout)

        angle.setValue(60)
        force.setValue(25)
        angle.setFocus()

        self.newGame()
예제 #11
0
 def define_shortcuts(self):
     QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Space), self,
                     self.btn_play.click)
예제 #12
0
    def __init__(self):
        """Initialize the class."""

        super().__init__()

        # Preflight
        self.check_for_updates(silent=True)

        self.ui = QUiLoader().load(resources.path("tailor.resources", "tailor.ui"))
        self.ui.setWindowIcon(
            QtGui.QIcon(str(resources.path("tailor.resources", "tailor.png")))
        )
        # store reference to this code in data tab
        self.ui.data.code = self

        # set up dirty timer
        self._dirty_timer = QtCore.QTimer()
        self._dirty_timer.timeout.connect(self.mark_project_dirty)

        # clear all program state
        self.clear_all()

        # Enable close buttons...
        self.ui.tabWidget.setTabsClosable(True)
        # ...but remove them for the table view
        for pos in QtWidgets.QTabBar.LeftSide, QtWidgets.QTabBar.RightSide:
            widget = self.ui.tabWidget.tabBar().tabButton(0, pos)
            if widget:
                widget.close()

        # connect button signals
        self.ui.add_column_button.clicked.connect(self.add_column)
        self.ui.add_calculated_column_button.clicked.connect(self.add_calculated_column)

        # connect menu items
        self.ui.actionQuit.triggered.connect(self.ui.close)
        self.ui.actionAbout_Tailor.triggered.connect(self.show_about_dialog)
        self.ui.actionNew.triggered.connect(self.new_project)
        self.ui.actionOpen.triggered.connect(self.open_project_dialog)
        self.ui.actionSave.triggered.connect(self.save_project_or_dialog)
        self.ui.actionSave_As.triggered.connect(self.save_as_project_dialog)
        self.ui.actionCheck_for_updates.triggered.connect(self.check_for_updates)
        self.ui.actionImport_CSV.triggered.connect(self.import_csv)
        self.ui.actionExport_CSV.triggered.connect(self.export_csv)
        self.ui.actionExport_Graph_to_PDF.triggered.connect(
            lambda: self.export_graph(".pdf")
        )
        self.ui.actionExport_Graph_to_PNG.triggered.connect(
            lambda: self.export_graph(".png")
        )
        self.ui.actionClose.triggered.connect(self.new_project)
        self.ui.actionAdd_column.triggered.connect(self.add_column)
        self.ui.actionAdd_calculated_column.triggered.connect(
            self.add_calculated_column
        )
        self.ui.actionAdd_row.triggered.connect(self.add_row)
        self.ui.actionRemove_column.triggered.connect(self.remove_column)
        self.ui.actionRemove_row.triggered.connect(self.remove_row)
        self.ui.actionClear_Cell_Contents.triggered.connect(self.clear_selected_cells)

        # set up the open recent menu
        self.ui._recent_files_separator = self.ui.menuOpen_Recent.insertSeparator(
            self.ui.actionClear_Menu
        )
        self.update_recent_files()
        self.ui.actionClear_Menu.triggered.connect(self.clear_recent_files_menu)

        # user interface events
        self.ui.data_view.horizontalHeader().sectionMoved.connect(self.column_moved)
        self.ui.tabWidget.currentChanged.connect(self.tab_changed)
        self.ui.tabWidget.tabCloseRequested.connect(self.close_tab)
        self.ui.name_edit.textEdited.connect(self.rename_column)
        self.ui.formula_edit.textEdited.connect(self.update_column_expression)
        self.ui.create_plot_button.clicked.connect(self.ask_and_create_plot_tab)

        # install event filter to capture UI events (which are not signals)
        # necessary to caputer closeEvent inside QMainWindow widget
        self.ui.installEventFilter(self)

        # Set standard shortcuts for menu items
        self.ui.actionNew.setShortcut(QtGui.QKeySequence.New)
        self.ui.actionOpen.setShortcut(QtGui.QKeySequence.Open)
        self.ui.actionClose.setShortcut(QtGui.QKeySequence.Close)
        self.ui.actionSave.setShortcut(QtGui.QKeySequence.Save)
        self.ui.actionSave_As.setShortcut(QtGui.QKeySequence.SaveAs)

        # Set other shortcuts for menu items
        self.ui.actionImport_CSV.setShortcut(QtGui.QKeySequence("Ctrl+I"))
        self.ui.actionImport_CSV_Into_Current_Project.setShortcut(
            QtGui.QKeySequence("Shift+Ctrl+I")
        )
        self.ui.actionExport_CSV.setShortcut(QtGui.QKeySequence("Ctrl+E"))
        self.ui.actionExport_Graph_to_PDF.setShortcut(QtGui.QKeySequence("Ctrl+G"))
        self.ui.actionExport_Graph_to_PNG.setShortcut(
            QtGui.QKeySequence("Shift+Ctrl+G")
        )

        # Create shortcut for return/enter keys
        for key in QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter:
            QtGui.QShortcut(
                QtGui.QKeySequence(key), self.ui.data_view, self.edit_or_move_down
            )
        # Shortcut for backspace and delete: clear cell contents
        for key in QtCore.Qt.Key_Backspace, QtCore.Qt.Key_Delete:
            QtGui.QShortcut(
                QtGui.QKeySequence(key), self.ui.data_view, self.clear_selected_cells
            )

        # Start at (0, 0)
        self.ui.data_view.setCurrentIndex(self.data_model.createIndex(0, 0))