def make_progress(msg,total_steps): progress = QProgressDialog(msg, None, 0, total_steps, None) progress.setWindowTitle("Horse") progress.setMinimumDuration(0) progress.setWindowModality(Qt.WindowModal) progress.setValue( progress.value() + 1) progress.show() return progress
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.build_dir_tree() self.setWindowIcon(QIcon('favicon.png')) self.actionAbout.triggered.connect(self.about) self.destButton.clicked.connect(self.destination_chooser) self.actionChoose_Destination.triggered.connect( self.destination_chooser) self.copyButton.clicked.connect(self.copy_files) self.actionStart_Copy.triggered.connect(self.copy_files) self.ckbxTrimDir.toggled.connect(self.update_table_view) self.treeView.expanded.connect(self.resize_tree_column) self.treeView.collapsed.connect(self.resize_tree_column) self.treeView.clicked.connect(self.update_table_view) self.trimdirCount.valueChanged.connect(self.update_table_view) self.listWidget.doubleClicked.connect(self.unselectItem) self.copyButton.setEnabled(False) self.lblTrimDir.setVisible(False) self.trimdirCount.setVisible(False) self.rbOWNewer.setVisible(False) self.rbOWLarger.setVisible(False) self.rbOWEither.setVisible(False) self.context = zmq.Context() self.socket = self.context.socket(zmq.PAIR) self.socket.bind("tcp://*:%s" % zmq_port) self.copyWorker = CopyWorker() self.connect( self.copyWorker, SIGNAL("copyComplete(QString, QString, QString, QString)"), self.copy_complete, Qt.QueuedConnection) self.connect(self.copyWorker, SIGNAL("spaceProblem(int, int)"), self.space_problem, Qt.QueuedConnection) def unselectItem(self, item): ##need to figure out how to remove from the model self.listWidget.takeItem(item.row()) def copy_complete(self, filecount, filesize, runtime, run_seconds): self.progress.setValue(self.progress.maximum()) transfer_rate = round((float(filesize) * 1024) / float(run_seconds), 3) filesize = round(float(filesize), 3) QMessageBox.information( self, "File Copy Complete", """Your file copy has been successfully completed.\n Files processed:\t%s\n Data copied:\t%sGB\n Total runtime:\t%s\n Transfer Rate:\t%sMB/Sec""" % (filecount, filesize, runtime, transfer_rate), WindowModility=True) self.copyButton.setEnabled(True) def space_problem(self, dirsize, filesize): """Display a dialog to the user advising that there is not enough space in the destination directory. Input: dirsize : integer - amount of space available in the destination directory filesize: integer - size of the selected files Output: None, dialog is displayed to the user.""" ##TODO: Set the messagebox modal property to true required_space = (filesize / 1024.00 / 1024.00 / 1024.00) - (dirsize / 1024.00 / 1024.00 / 1024.00) QMessageBox.critical( self, "Not enough space", """You do not have enough space in your selected destination to complete this operation\n %s more GB space required""" % required_space, WindowModility=True) self.copyWorker.quit() self.copyButton.setEnabled(True) def build_dir_tree(self): """Add a directory tree listing to the QTreeView and set the root to the drive that it was run from. Input: None Output: None""" ##TODO: add linux support for the model root drive. self.model = QFileSystemModel(self) if sys.platform == 'win32': self.model.setRootPath(os.path.splitdrive(os.getcwd())[0]) self.tree = self.treeView self.tree.setModel(self.model) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) def update_table_view(self): """Refresh listview with selected items in the treeView using the shared model. Input: None Output: None""" itemlist = [ os.path.abspath( self.model.filePath( self.model.index(selection.row(), 0, selection.parent()))) for selection in self.treeView.selectedIndexes() ] self.listWidget.clear() self.listWidget.addItems(itemlist) nitemlist = [] fileops = FileOperations() if not self.ckbxTrimDir.isChecked(): flattencount = 0 else: flattencount = self.trimdirCount.value() if self.lblDestPath.isEnabled(): self.previewView.clear() for item in itemlist: nitemlist.append( fileops.get_dest_filepath(item, self.lblDestPath.text(), flattencount)) self.previewView.addItems(nitemlist) else: self.previewView.clear() self.previewView.addItems(['No destination folder selected']) self.resize_tree_column() def resize_tree_column(self): """Resize the treeView column to fit the contents. Input: None Output: None""" self.treeView.resizeColumnToContents(0) def copy_files(self): """Initiate copy process. File size is calculated first to check that there is enough space in the destination. If there is enough space then we start the copy of the files to their destination. Input: None Output: None""" self.copyButton.setEnabled(False) self.copyWorker.must_run = True self.connect(self.copyWorker, SIGNAL("copyProgress(QString, QString, QString)"), self.copy_progress, Qt.QueuedConnection) dest_dir = self.lblDestPath.text() if dest_dir == '': QMessageBox.critical(self, "Destination not set", "Please specify a destination path", WindowModility=True) else: copy_filelist = [] for selection in self.treeView.selectedIndexes(): indexItem = self.model.index(selection.row(), 0, selection.parent()) copy_filelist.append(self.model.filePath(indexItem)) if self.cbOWDest.isChecked(): if self.rbOWEither.isChecked(): overwrite_option = 'either' elif self.rbOWLarger.isChecked(): overwrite_option = 'larger' elif self.rbOWNewer.isChecked(): overwrite_option = 'newer' else: QMessageBox.critical( self, "Overwrite option missing", """You did not select an overwrite option.""", WindowModility=True) self.copyButton.setEnabled(True) return else: overwrite_option = None if not self.ckbxTrimDir.isChecked(): flattencount = 0 else: flattencount = self.trimdirCount.value() self.progress = QProgressDialog("Copy in progress.", "Cancel", 0, 100, modal=True) self.progress.canceled.connect(self.cancel_copy) self.progress.setWindowTitle('Copy Progress') var_values = { 'destdir': dest_dir, 'filelist': copy_filelist, 'flattencount': flattencount, 'overwrite_opt': overwrite_option } self.socket.send(json.dumps(var_values)) self.copyWorker.start() def copy_progress(self, percentage_complete, filecount, filecomplete): """Display the progress bar with a completed percentage. Input: percentage_complete : integer - the amount complete in percent. filecount : integer - the total number of files being processed. filecomplete : integer - the number of files that have already been processed. Output: None, dialog is updated""" ##TODO: display the current transfer rate ##TODO: display the current file being transferred and possibly the progress thereof. ##Perhaps use the statusbar method for this self.progress.setValue(int(percentage_complete)) def cancel_copy(self): """Slot for the cancel command on the progress dialog. The must_run variable of the copyWorker class is set to False to terminate the copy. Input: None Output: None""" self.copyWorker.must_run = False self.copyButton.setEnabled(True) def statusbar_msg(self, msg): """Update the statusbar on the bottom of the screen. Input: msg : string - Message that you would like displayed on the form. Output: None """ self.statusbar.clearMessage() self.statusbar.showMessage(msg) def destination_chooser(self): """Show folder chooser dialog and update lblDestPath with path selected. Input: None Output: None""" dialog = QFileDialog() dialog.setFileMode(QFileDialog.Directory) dialog.setOption(QFileDialog.ShowDirsOnly) dialog.exec_() self.lblDestPath.setEnabled(True) self.lblDestPath.setText( os.path.abspath(dialog.directory().absolutePath())) self.update_table_view() self.copyButton.setEnabled(True) def about(self): """Popup a box with about message. Input: None Output: None""" QMessageBox.about( self, "About MClub Mover", """This program is designed to help make the process of copying \ files from multiple directories much easier and simpler.\n This software is provided as is with absolutely no warranties.""", WindowModility=True)
class Gui(): """main gui class""" def __init__(self): self.mainwindow = QMainWindow() settings.get_settings() self.access = tuple(settings.access.items()) self.progress = QProgressDialog("Setting up modules...", "cancel", 0, 7, self.mainwindow) self.progress.setWindowTitle( QApplication.translate("MainWindow", str(settings.company), None, QApplication.UnicodeUTF8)) def setup(self): """initializes the uio of the erp client""" self.progress.setFixedWidth(1000) self.progress.setCancelButton(None) # self.progress.setWindowModality(Qt.WindowModal) self.progress.setValue(1) self.mainwindow.setObjectName("MainWindow") self.mainwindow.resize(832, 668) self.mainwindow.setStyleSheet( "QToolBar{\n" "background: qlineargradient(x1:0, y1:0, x2:1, y2:1,\n" "stop:0 rgba(0,0,0),stop:1 rgb(162, 162, 162, 162));\n" "border: 0px;\n" "}\n" "QToolBar > QWidget{\n" "color:white;\n" "}\n" "QToolBar > QWidget:hover {\n" "background:transparent;\n" " }\n" "QToolBar > QWidget:checked {\n" "background:transparent;\n" " }\n" "#MainWindow{\n" "background: qlineargradient(x1:0, y1:0, x2:1, y2:1,\n" "stop:0 rgba(0,0,0),stop:1 rgb(162, 162, 162, 162));\n" "border: 0px;\n" "}\n" "") self.centralWidget = QWidget(self.mainwindow) self.centralWidget.setObjectName("centralWidget") self.gridLayout_2 = QGridLayout(self.centralWidget) self.gridLayout_2.setObjectName("gridLayout_2") self.stackedWidget = QStackedWidget(self.centralWidget) self.stackedWidget.setStyleSheet("") self.stackedWidget.setObjectName("stackedWidget") self.shortcut = NewShortcut() scroll = QScrollArea() scroll.setWidget(self.shortcut.shortcut_setting) self.stackedWidget.addWidget(self.shortcut.shortcut_setting) self.home_page = QWidget() self.home_page.setObjectName("home_page") self.gridLayout = QGridLayout(self.home_page) self.gridLayout.setObjectName("gridLayout") self.billing_frame_2 = QFrame(self.home_page) self.billing_frame_2.setStyleSheet( "background-image:url(:/images/billing_frame.png);\n" "background-repeat: no-repeat;\n" "background-position: center;\n" "background-color:#6CBED2;") self.billing_frame_2.setFrameShape(QFrame.StyledPanel) self.billing_frame_2.setFrameShadow(QFrame.Raised) self.billing_frame_2.setObjectName("billing_frame_2") self.verticalLayout_4 = QVBoxLayout(self.billing_frame_2) self.verticalLayout_4.setObjectName("verticalLayout_4") spacerItem = QSpacerItem(20, 217, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_4.addItem(spacerItem) self.label_10 = QLabel(self.billing_frame_2) self.label_10.setStyleSheet("background:transparent;") self.label_10.setObjectName("label_10") self.verticalLayout_4.addWidget(self.label_10) self.gridLayout.addWidget(self.billing_frame_2, 0, 1, 1, 1) self.employee_frame_3 = QFrame(self.home_page) self.employee_frame_3.setStyleSheet( "background-image:url(:/images/employee_frame.png);\n" "background-repeat: no-repeat;\n" "background-position: center;\n" "background-color:#0099CC;") self.employee_frame_3.setFrameShape(QFrame.StyledPanel) self.employee_frame_3.setFrameShadow(QFrame.Raised) self.employee_frame_3.setObjectName("employee_frame_3") self.verticalLayout_5 = QVBoxLayout(self.employee_frame_3) self.verticalLayout_5.setObjectName("verticalLayout_5") spacerItem1 = QSpacerItem(20, 217, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_5.addItem(spacerItem1) self.label_11 = QLabel(self.employee_frame_3) self.label_11.setStyleSheet("background:transparent;") self.label_11.setObjectName("label_11") self.verticalLayout_5.addWidget(self.label_11) self.gridLayout.addWidget(self.employee_frame_3, 0, 2, 1, 1) self.menu_frame_4 = QFrame(self.home_page) self.menu_frame_4.setStyleSheet( "background-image:url(:/images/menu_frame.png);\n" "background-repeat: no-repeat;\n" "background-position: center;\n" "background-color:#297ACC;") self.menu_frame_4.setFrameShape(QFrame.StyledPanel) self.menu_frame_4.setFrameShadow(QFrame.Raised) self.menu_frame_4.setObjectName("menu_frame_4") self.verticalLayout_3 = QVBoxLayout(self.menu_frame_4) self.verticalLayout_3.setObjectName("verticalLayout_3") spacerItem2 = QSpacerItem(20, 216, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_3.addItem(spacerItem2) self.label_12 = QLabel(self.menu_frame_4) self.label_12.setStyleSheet("background:transparent;") self.label_12.setObjectName("label_12") self.verticalLayout_3.addWidget(self.label_12) self.gridLayout.addWidget(self.menu_frame_4, 1, 0, 1, 1) self.report_frame_5 = QFrame(self.home_page) self.report_frame_5.setStyleSheet( "background-image:url(:/images/report_frame.png);\n" "background-repeat: no-repeat;\n" "background-position: center;\n" "background-color:#006BB2;") self.report_frame_5.setFrameShape(QFrame.StyledPanel) self.report_frame_5.setFrameShadow(QFrame.Raised) self.report_frame_5.setObjectName("report_frame_5") self.verticalLayout_6 = QVBoxLayout(self.report_frame_5) self.verticalLayout_6.setObjectName("verticalLayout_6") spacerItem3 = QSpacerItem(20, 216, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_6.addItem(spacerItem3) self.label_13 = QLabel(self.report_frame_5) self.label_13.setStyleSheet("background:transparent;") self.label_13.setObjectName("label_13") self.verticalLayout_6.addWidget(self.label_13) self.gridLayout.addWidget(self.report_frame_5, 1, 1, 1, 1) self.waste_frame_6 = QFrame(self.home_page) self.waste_frame_6.setStyleSheet( "background-image:url(:/images/waste_frame.png);\n" "background-repeat: no-repeat;\n" "background-position: center;\n" "background-color:#003D7A;") self.waste_frame_6.setFrameShape(QFrame.StyledPanel) self.waste_frame_6.setFrameShadow(QFrame.Raised) self.waste_frame_6.setObjectName("waste_frame_6") self.verticalLayout_7 = QVBoxLayout(self.waste_frame_6) self.verticalLayout_7.setObjectName("verticalLayout_7") spacerItem4 = QSpacerItem(20, 216, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_7.addItem(spacerItem4) self.label_14 = QLabel(self.waste_frame_6) self.label_14.setStyleSheet("background:transparent;") self.label_14.setObjectName("label_14") self.verticalLayout_7.addWidget(self.label_14) self.gridLayout.addWidget(self.waste_frame_6, 1, 2, 1, 1) self.inventory_frame_1 = QFrame(self.home_page) self.inventory_frame_1.setStyleSheet( "background-image:url(:/images/inventory_frame.png);\n" "background-repeat: no-repeat;\n" "background-position: center;\n" "background-color:#ADEBFF;") self.inventory_frame_1.setFrameShape(QFrame.StyledPanel) self.inventory_frame_1.setFrameShadow(QFrame.Raised) self.inventory_frame_1.setObjectName("inventory_frame_1") self.verticalLayout_2 = QVBoxLayout(self.inventory_frame_1) self.verticalLayout_2.setObjectName("verticalLayout_2") spacerItem5 = QSpacerItem(20, 217, QSizePolicy.Minimum, QSizePolicy.Expanding) self.verticalLayout_2.addItem(spacerItem5) self.label_9 = QLabel(self.inventory_frame_1) self.label_9.setStyleSheet("background:transparent;") self.label_9.setObjectName("label_9") self.verticalLayout_2.addWidget(self.label_9) self.gridLayout.addWidget(self.inventory_frame_1, 0, 0, 1, 1) self.stackedWidget.addWidget(self.home_page) self.detail_page = QWidget() self.detail_page.setObjectName("detail_page") self.horizontalLayout_2 = QHBoxLayout(self.detail_page) self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.main_tabWidget = QTabWidget(self.detail_page) self.main_tabWidget.setAutoFillBackground(False) self.main_tabWidget.setStyleSheet("") self.main_tabWidget.setTabPosition(QTabWidget.West) self.main_tabWidget.setIconSize(QSize(60, 60)) self.main_tabWidget.setElideMode(Qt.ElideNone) self.main_tabWidget.setObjectName("main_tabWidget") ##initializes the tabs self.add_tabs() self.main_tabWidget.setFocusPolicy(Qt.StrongFocus) self.main_tabWidget.focusInEvent = self.change_focus self.main_tabWidget.currentChanged.connect(self.change_focus) self.stackedWidget.currentChanged.connect(self.change_focus) ###### self.horizontalLayout_2.addWidget(self.main_tabWidget) self.stackedWidget.addWidget(self.detail_page) if ('Admin', True) in self.access: self.stackedWidget.addWidget(Admin(self.mainwindow)) notification = NotificationTab() tab = notification.notificationTab_tab_4 tab.custom_class_object = notification # class_object is used to access the api through the self.stackedWidget.addWidget(tab) self.gridLayout_2.addWidget(self.stackedWidget, 0, 0, 1, 1) self.mainwindow.setCentralWidget(self.centralWidget) self.menuBar = QMenuBar(self.mainwindow) self.menuBar.setGeometry(QRect(0, 0, 832, 29)) self.menuBar.setObjectName("menuBar") self.mainwindow.setMenuBar(self.menuBar) self.mainToolBar = QToolBar(self.mainwindow) self.mainToolBar.setLayoutDirection(Qt.RightToLeft) self.mainToolBar.setStyleSheet("") self.mainToolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.mainToolBar.setObjectName("mainToolBar") self.mainwindow.addToolBar(Qt.TopToolBarArea, self.mainToolBar) self.statusBar = QStatusBar(self.mainwindow) self.statusBar.setObjectName("statusBar") self.mainwindow.setStatusBar(self.statusBar) self.toolBar = QToolBar(self.mainwindow) self.toolBar.setLayoutDirection(Qt.RightToLeft) self.toolBar.setStyleSheet("") self.toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.toolBar.setObjectName("toolBar") self.mainwindow.addToolBar(Qt.TopToolBarArea, self.toolBar) self.actionNotification = QAction(self.mainwindow) self.actionNotification.setCheckable(True) self.actionNotification.setChecked(False) self.actionNotification.setEnabled(True) icon6 = QIcon() icon6.addPixmap(QPixmap(":/images/notification.png"), QIcon.Normal, QIcon.Off) self.actionNotification.setIcon(icon6) self.actionNotification.setAutoRepeat(True) self.actionNotification.setVisible(True) self.actionNotification.setIconVisibleInMenu(False) self.actionNotification.setObjectName("actionNotification") self.actionNotification self.actionAdmin = QAction(self.mainwindow) # self.actionAdmin.setCheckable(True) icon7 = QIcon() icon7.addPixmap(QPixmap(":/images/admin.png"), QIcon.Normal, QIcon.Off) self.actionAdmin.setIcon(icon7) self.actionAdmin.setObjectName("actionAdmin") self.actionRefresh = QAction(self.mainwindow) icon8 = QIcon() icon8.addPixmap(QPixmap(":/images/refresh.png"), QIcon.Normal, QIcon.Off) self.actionRefresh.setIcon(icon8) self.actionRefresh.setObjectName("actionRefresh") self.actionHome = QAction(self.mainwindow) # self.actionHome.setCheckable(True) icon9 = QIcon() icon9.addPixmap(QPixmap(":/images/home.png"), QIcon.Normal, QIcon.Off) self.actionHome.setIcon(icon9) self.actionHome.setObjectName("actionHome") self.actionSettings = QAction(self.mainwindow) icon10 = QIcon() icon10.addPixmap(QPixmap(":/images/settings.png"), QIcon.Normal, QIcon.Off) self.actionSettings.setIcon(icon10) self.actionSettings.setObjectName("actionRefresh") self.toolBar.addAction(self.actionNotification) self.toolBar.addSeparator() self.toolBar.addAction(self.actionAdmin) if ('Admin', True) in self.access: self.toolBar.addSeparator() else: self.actionAdmin.setVisible(False) self.toolBar.addAction(self.actionHome) self.toolBar.addSeparator() self.toolBar.addAction(self.actionRefresh) self.toolBar.addSeparator() self.toolBar.addAction(self.actionSettings) ##retranslates self.mainwindow.setWindowTitle( QApplication.translate("MainWindow", settings.company, None, QApplication.UnicodeUTF8)) self.label_10.setText( QApplication.translate( "MainWindow", "<html><head/><body><p align=\"center\">BILLING</p></body></html>", None, QApplication.UnicodeUTF8)) self.label_11.setText( QApplication.translate( "MainWindow", "<html><head/><body><p align=\"center\">EMPLOYEE</p></body></html>", None, QApplication.UnicodeUTF8)) self.label_12.setText( QApplication.translate( "MainWindow", "<html><head/><body><p align=\"center\">MENU</p></body></html>", None, QApplication.UnicodeUTF8)) self.label_13.setText( QApplication.translate( "MainWindow", "<html><head/><body><p align=\"center\">REPORT</p></body></html>", None, QApplication.UnicodeUTF8)) self.label_14.setText( QApplication.translate( "MainWindow", "<html><head/><body><p align=\"center\">WASTE</p></body></html>", None, QApplication.UnicodeUTF8)) self.label_9.setText( QApplication.translate( "MainWindow", "<html><head/><body><p align=\"center\">INVENTORY</p></body></html>", None, QApplication.UnicodeUTF8)) self.inventory_frame_1.setToolTip( QApplication.translate("MainWindow", "Go to the Inventory Tab", None, QApplication.UnicodeUTF8)) self.billing_frame_2.setToolTip( QApplication.translate("MainWindow", "Go to the Billing Tab", None, QApplication.UnicodeUTF8)) self.employee_frame_3.setToolTip( QApplication.translate("MainWindow", "Go to the Employee Tab", None, QApplication.UnicodeUTF8)) self.menu_frame_4.setToolTip( QApplication.translate("MainWindow", "Go to the Menu Tab", None, QApplication.UnicodeUTF8)) self.report_frame_5.setToolTip( QApplication.translate("MainWindow", "Go to the Report Tab", None, QApplication.UnicodeUTF8)) self.waste_frame_6.setToolTip( QApplication.translate("MainWindow", "Go to the Waste Tab", None, QApplication.UnicodeUTF8)) self.toolBar.setWindowTitle( QApplication.translate("MainWindow", "toolBar", None, QApplication.UnicodeUTF8)) self.actionNotification.setText("&&Notification") # QApplication.translate("MainWindow", "&Notification", None, QApplication.UnicodeUTF8)) self.actionNotification.setToolTip( QApplication.translate("MainWindow", "Click to see new notifications", None, QApplication.UnicodeUTF8)) # self.actionNotification.setShortcut( # QApplication.translate("MainWindow", "Ctrl+Shift+N", None, QApplication.UnicodeUTF8)) self.actionAdmin.setText('&&Admin') # QApplication.translate("MainWindow", "Admin", None, QApplication.UnicodeUTF8)) self.actionAdmin.setToolTip( QApplication.translate("MainWindow", "Click to go to admin interface", None, QApplication.UnicodeUTF8)) # self.actionAdmin.setShortcut( # QApplication.translate("MainWindow", "Ctrl+Shift+A", None, QApplication.UnicodeUTF8)) self.actionRefresh.setText("&&Refresh") # QApplication.translate("MainWindow", "Refresh", None, QApplication.UnicodeUTF8)) self.actionRefresh.setToolTip( QApplication.translate("MainWindow", "refreshes the data from the server", None, QApplication.UnicodeUTF8)) # self.actionRefresh.setShortcut( # QApplication.translate("MainWindow", "Ctrl+Shift+R", None, QApplication.UnicodeUTF8)) self.actionHome.setText('&&Home') # QApplication.translate("MainWindow", "Home", None, QApplication.UnicodeUTF8)) self.actionHome.setToolTip( QApplication.translate("MainWindow", "Go back to the home screen", None, QApplication.UnicodeUTF8)) self.actionSettings.setText('&&Settings') # QApplication.translate("MainWindow", "Settings", None, QApplication.UnicodeUTF8)) self.actionSettings.setToolTip( QApplication.translate("MainWindow", "Go to the settings panel", None, QApplication.UnicodeUTF8)) # self.actionHome.setShortcut( # QApplication.translate("MainWindow", "Ctrl+Shift+H", None, QApplication.UnicodeUTF8)) self.stackedWidget.setCurrentIndex(1) self.main_tabWidget.setCurrentIndex(0) self.ob = self.main_tabWidget.tabBar() # self.add_tool_tip(self.ob) todo avoided due to segmentation fault error, left for future fixes self.tb = EventHandlerForTabBar() self.ob.installEventFilter(self.tb) QMetaObject.connectSlotsByName(self.mainwindow) def add_tabs(self): """ adds new tabs """ global logger if ('Inventory', True) in self.access: logger.info('initiating Inventory') icon = QIcon() icon.addPixmap(QPixmap(":/images/inventory.png"), QIcon.Normal, QIcon.Off) from inventory.inventory import Inventory inventory = Inventory() # inventory.inventory_tab_1.setToolTip("Inventory Section") self.main_tabWidget.addTab(inventory.inventory_tab_1, icon, "") inventory.inventory_detail_tabWidget.setCurrentIndex(0) else: self.inventory_frame_1.setVisible(False) self.progress.setLabelText('Inventory Done....') self.progress.setValue(2) if ('Billing', True) in self.access: logger.info('initiating Billing') icon1 = QIcon() icon1.addPixmap(QPixmap(":/images/billing.png"), QIcon.Normal, QIcon.Off) from billing.billing import Billing bill = Billing() # bill.billing_tab_2.setToolTip("Billing Section") self.main_tabWidget.addTab(bill.billing_tab_2, icon1, "") bill.billing_detail_tabWidget.setCurrentIndex(0) else: self.billing_frame_2.setVisible(False) self.progress.setLabelText('Billing Done...') self.progress.setValue(3) if ('Employee', True) in self.access: logger.info('initiating Employee') icon2 = QIcon() icon2.addPixmap(QPixmap(":/images/employee.png"), QIcon.Normal, QIcon.Off) from employee.employee import Employee employee = Employee() # employee.employee_tab_3.setToolTip("Employee Section") self.main_tabWidget.addTab(employee.employee_tab_3, icon2, "") employee.employee_detail_tabWidget.setCurrentIndex(0) else: self.employee_frame_3.setVisible(False) self.progress.setLabelText('Employee Done...') self.progress.setValue(4) if ('Menu', True) in self.access: logger.info('initiating Menu') icon3 = QIcon() icon3.addPixmap(QPixmap(":/images/menu.png"), QIcon.Normal, QIcon.Off) from menu.menu import Menu menu = Menu() # menu.menu_tab_4.setToolTip("Menu Section") self.main_tabWidget.addTab(menu.menu_tab_4, icon3, "") menu.menu_detail_tabWidget.setCurrentIndex(0) else: self.menu_frame_4.setVisible(False) self.progress.setLabelText('Menu Done....') self.progress.setValue(5) if ('Report', True) in self.access: logger.info('initiating Report') icon4 = QIcon() icon4.addPixmap(QPixmap(":/images/report.png"), QIcon.Normal, QIcon.Off) from report.report import Report report = Report() # report.report_tab_5.setToolTip("Report Section") self.main_tabWidget.addTab(report.report_tab_5, icon4, "") report.report_detail_tabWidget.setCurrentIndex(0) else: self.report_frame_5.setVisible(False) self.progress.setLabelText('Report Done....') self.progress.setValue(6) if ('Waste', True) in self.access: logger.info('initiating Waste') icon5 = QIcon() icon5.addPixmap(QPixmap(":/images/waste.png"), QIcon.Normal, QIcon.Off) from waste.waste import Waste waste = Waste() # waste.waste_tab_6.setToolTip("Waste Section") self.main_tabWidget.addTab(waste.waste_tab_6, icon5, "") waste.waste_detail_tabWidget.setCurrentIndex(0) else: self.waste_frame_6.setVisible(False) self.progress.setLabelText('Waste Done....') self.progress.setValue(7) def change_focus(self, event=None): """ focus method to set focus to a tab to initialize the corresponding events of the tab """ wid = self.main_tabWidget.currentWidget() if wid: if wid.isVisible(): # print wid.objectName() # print '1y' wid.setFocus() def add_tool_tip( self, ob ): # todo not working causing segmentation fault, avoided calling this function """ method to add tool tip to the tabs :param ob: Tab bar """ obj = ob count = obj.count() hardcode = { 0: 'Inventory Section', 1: "Billing Section", 2: "Employee Section", 3: "Menu Section", 4: "Report Section", 5: "Waste Section" } for i in range(count): obj.setTabToolTip(i, hardcode[i])
def reload(self, order_overview_widget, all_ops, all_operations, sort=1): # mainlog.debug("reload...") progress = QProgressDialog(_("Collecting data..."), None, 0, len(all_ops) + 3, order_overview_widget) progress.setWindowTitle("Horse") progress.setMinimumDuration(0) progress.setWindowModality(Qt.WindowModal) progress.setValue(progress.value() + 1) progress.show() for i in self.items(): self.removeItem(i) self.posts_offsets = dict() self.drawn_operations_data = dict() self.cursor = QGraphicsRectItem(0, 0, 50, 300) self.cursor.setBrush(QBrush(QColor(208, 208, 255, 255))) self.cursor.setPen(QPen(Qt.transparent)) self.addItem(self.cursor) bar_width = 8 bar_height = int(bar_width * 60.0 / 8.0) ascent = QFontMetrics(self.base_font).ascent() ascent_big = QFontMetrics(self.base_font_big).ascent() post_ops = {} # mainlog.debug("reload...2") # z = 0 # for op,order_part,parts in all_operations: # z = op.planned_hours # z = order_part.deadline # z = order_part.qty # z = order_part.human_identifier # all_operations = map(lambda i:i[0],all_operations) y = 0 for opdef in all_ops: progress.setValue(progress.value() + 1) operations = filter( lambda op: op.operation_definition_id == opdef. operation_definition_id, all_operations) # We're only interested in the effort/time that remains # to be put on an operation. We're only interested in # the future. # We want the oeprations that are either # - ongoing # - ready to start. # In all cases we're only interested in operations # that are "active" if sort == 1: operations = sorted( operations, key=lambda op: op.deadline or date(3000, 1, 1)) elif sort == 2: operations = sorted( operations, key=lambda op: op.planned_hours * op.qty - op.done_hours) else: # Don't sort pass maximum = 16.0 #float ! small_hours = 0 op_ndx = 0 current_x = 50 bar_drawn = False total_done_hours = total_estimated = 0 # -------------------------------------------------------------- # Started operations bars_line = BarsLine(16, bar_width, bar_height, current_x, y, self, order_overview_widget) total_hours_to_do = 0 for op in filter(lambda op: op.done_hours > 0, operations): hours_to_do = max( 0, op.planned_hours * op.qty - op.done_hours) # max protects against reporting errors total_hours_to_do += hours_to_do total_estimated += op.planned_hours * op.qty total_done_hours += op.done_hours bars_line.add_bar(hours_to_do, QBrush(Qt.green), self._operation_hoover_description(op), False, None) # op.production_file.order_part) # -------------------------------------------------------------- bars_line_unstarted_operations = BarsLine(16, bar_width, bar_height, current_x + 30, y, self, order_overview_widget) total_hours_to_do_on_unstarted_operations = 0 for op in filter(lambda op: op.done_hours == 0, operations): hours_to_do = op.planned_hours * op.qty total_hours_to_do_on_unstarted_operations += hours_to_do total_estimated += hours_to_do bars_line_unstarted_operations.add_bar( hours_to_do, QBrush(Qt.yellow), self._operation_hoover_description(op), False, None) #op.production_file.order_part) y_start = y total = total_hours_to_do + total_hours_to_do_on_unstarted_operations if total > 0: self.drawn_operations_data[ opdef.operation_definition_id] = "{}h".format( int(round(total_estimated))) gi = QGraphicsSimpleTextItem( _("{} - Estimated to do : {}h; done : {}h").format( opdef.description, int(round(total)), int(round(total_done_hours)))) gi.setFont(self.base_font_big) gi.setPos(0, y - gi.boundingRect().height()) self.addItem(gi) th = gi.boundingRect().height() gi = QGraphicsLineItem(-ascent_big, y, 1024 + 2 * ascent_big, y) gi.setPen(QPen(Qt.black)) self.addItem(gi) y += th else: continue y_bars = y if total_hours_to_do > 0: # There's something to draw head = QGraphicsSimpleTextItem(_("Started")) head.setFont(self.base_font) head.setPos(current_x, y) self.addItem(head) y += head.boundingRect().height() y += bar_height bars_line.set_start_pos(current_x, y) bars_line.finish_bar() foot = QGraphicsSimpleTextItem( _("{}h").format(int(total_hours_to_do + 0.5))) foot.setFont(self.base_font) foot.setPos(current_x, y) self.addItem(foot) y += foot.boundingRect().height() current_x = max(current_x + bars_line.estimate_width(), head.boundingRect().right(), foot.boundingRect().right()) bar_drawn = True if total_hours_to_do_on_unstarted_operations > 0: if bars_line_unstarted_operations.estimate_width( ) + current_x > 1200: x = 50 y += ascent_big else: y = y_bars x = current_x + 50 head = QGraphicsSimpleTextItem(_("Not started yet")) head.setFont(self.base_font) head.setPos(x, y) self.addItem(head) y += head.boundingRect().height() y += bar_height bars_line_unstarted_operations.set_start_pos(x, y) bars_line_unstarted_operations.finish_bar() foot = QGraphicsSimpleTextItem( _("{}h").format( int(total_hours_to_do_on_unstarted_operations + 0.5))) foot.setFont(self.base_font) foot.setPos(x, y) self.addItem(foot) y += foot.boundingRect().height() bar_drawn = True y += 3 * ascent_big r = self.sceneRect() self.posts_offsets[opdef.operation_definition_id] = \ QRectF(r.x() - 2*ascent_big, y_start - 1.5*ascent_big, r.width() + 4*ascent_big, (y - ascent_big) - (y_start - 1.5*ascent_big) ) y += ascent_big # mainlog.debug("reload...3") import functools max_width = functools.reduce(lambda acc, po: max(acc, po.width()), self.posts_offsets.values(), 0) map(lambda po: po.setWidth(max_width), self.posts_offsets.values()) # for r in self.posts_offsets.values(): # gi = QGraphicsLineItem(r.x(),r.y(),r.x()+r.width(),r.y()) # gi.setPen(QPen(Qt.lightGray)) # self.addItem(gi) progress.close()
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.build_dir_tree() self.setWindowIcon(QIcon('favicon.png')) self.actionAbout.triggered.connect(self.about) self.destButton.clicked.connect(self.destination_chooser) self.actionChoose_Destination.triggered.connect(self.destination_chooser) self.copyButton.clicked.connect(self.copy_files) self.actionStart_Copy.triggered.connect(self.copy_files) self.ckbxTrimDir.toggled.connect(self.update_table_view) self.treeView.expanded.connect(self.resize_tree_column) self.treeView.collapsed.connect(self.resize_tree_column) self.treeView.clicked.connect(self.update_table_view) self.trimdirCount.valueChanged.connect(self.update_table_view) self.listWidget.doubleClicked.connect(self.unselectItem) self.copyButton.setEnabled(False) self.lblTrimDir.setVisible(False) self.trimdirCount.setVisible(False) self.rbOWNewer.setVisible(False) self.rbOWLarger.setVisible(False) self.rbOWEither.setVisible(False) self.context = zmq.Context() self.socket = self.context.socket(zmq.PAIR) self.socket.bind("tcp://*:%s" % zmq_port) self.copyWorker = CopyWorker() self.connect(self.copyWorker, SIGNAL("copyComplete(QString, QString, QString, QString)"), self.copy_complete, Qt.QueuedConnection) self.connect(self.copyWorker, SIGNAL("spaceProblem(int, int)"), self.space_problem, Qt.QueuedConnection) def unselectItem(self, item): ##need to figure out how to remove from the model self.listWidget.takeItem(item.row()) def copy_complete(self, filecount, filesize, runtime, run_seconds): self.progress.setValue(self.progress.maximum()) transfer_rate = round((float(filesize) * 1024) / float(run_seconds), 3) filesize = round(float(filesize), 3) QMessageBox.information(self, "File Copy Complete", """Your file copy has been successfully completed.\n Files processed:\t%s\n Data copied:\t%sGB\n Total runtime:\t%s\n Transfer Rate:\t%sMB/Sec""" % (filecount, filesize, runtime, transfer_rate), WindowModility=True) self.copyButton.setEnabled(True) def space_problem(self, dirsize, filesize): """Display a dialog to the user advising that there is not enough space in the destination directory. Input: dirsize : integer - amount of space available in the destination directory filesize: integer - size of the selected files Output: None, dialog is displayed to the user.""" ##TODO: Set the messagebox modal property to true required_space = (filesize / 1024.00 / 1024.00 / 1024.00) - (dirsize / 1024.00 / 1024.00 / 1024.00) QMessageBox.critical(self, "Not enough space", """You do not have enough space in your selected destination to complete this operation\n %s more GB space required""" % required_space, WindowModility=True) self.copyWorker.quit() self.copyButton.setEnabled(True) def build_dir_tree(self): """Add a directory tree listing to the QTreeView and set the root to the drive that it was run from. Input: None Output: None""" ##TODO: add linux support for the model root drive. self.model = QFileSystemModel(self) if sys.platform == 'win32': self.model.setRootPath(os.path.splitdrive(os.getcwd())[0]) self.tree = self.treeView self.tree.setModel(self.model) self.tree.setAnimated(False) self.tree.setIndentation(20) self.tree.setSortingEnabled(True) def update_table_view(self): """Refresh listview with selected items in the treeView using the shared model. Input: None Output: None""" itemlist = [os.path.abspath( self.model.filePath( self.model.index(selection.row(), 0, selection.parent() ) ) ) for selection in self.treeView.selectedIndexes()] self.listWidget.clear() self.listWidget.addItems(itemlist) nitemlist = [] fileops = FileOperations() if not self.ckbxTrimDir.isChecked(): flattencount = 0 else: flattencount = self.trimdirCount.value() if self.lblDestPath.isEnabled(): self.previewView.clear() for item in itemlist: nitemlist.append(fileops.get_dest_filepath(item, self.lblDestPath.text(), flattencount)) self.previewView.addItems(nitemlist) else: self.previewView.clear() self.previewView.addItems(['No destination folder selected']) self.resize_tree_column() def resize_tree_column(self): """Resize the treeView column to fit the contents. Input: None Output: None""" self.treeView.resizeColumnToContents(0) def copy_files(self): """Initiate copy process. File size is calculated first to check that there is enough space in the destination. If there is enough space then we start the copy of the files to their destination. Input: None Output: None""" self.copyButton.setEnabled(False) self.copyWorker.must_run = True self.connect(self.copyWorker, SIGNAL("copyProgress(QString, QString, QString)"), self.copy_progress, Qt.QueuedConnection) dest_dir = self.lblDestPath.text() if dest_dir == '': QMessageBox.critical(self, "Destination not set", "Please specify a destination path", WindowModility=True) else: copy_filelist = [] for selection in self.treeView.selectedIndexes(): indexItem = self.model.index(selection.row(), 0, selection.parent()) copy_filelist.append(self.model.filePath(indexItem)) if self.cbOWDest.isChecked(): if self.rbOWEither.isChecked(): overwrite_option = 'either' elif self.rbOWLarger.isChecked(): overwrite_option = 'larger' elif self.rbOWNewer.isChecked(): overwrite_option = 'newer' else: QMessageBox.critical(self, "Overwrite option missing", """You did not select an overwrite option.""", WindowModility=True) self.copyButton.setEnabled(True) return else: overwrite_option = None if not self.ckbxTrimDir.isChecked(): flattencount = 0 else: flattencount = self.trimdirCount.value() self.progress = QProgressDialog("Copy in progress.", "Cancel", 0, 100, modal=True) self.progress.canceled.connect(self.cancel_copy) self.progress.setWindowTitle('Copy Progress') var_values = {'destdir': dest_dir, 'filelist': copy_filelist, 'flattencount': flattencount, 'overwrite_opt': overwrite_option} self.socket.send(json.dumps(var_values)) self.copyWorker.start() def copy_progress(self, percentage_complete, filecount, filecomplete): """Display the progress bar with a completed percentage. Input: percentage_complete : integer - the amount complete in percent. filecount : integer - the total number of files being processed. filecomplete : integer - the number of files that have already been processed. Output: None, dialog is updated""" ##TODO: display the current transfer rate ##TODO: display the current file being transferred and possibly the progress thereof. ##Perhaps use the statusbar method for this self.progress.setValue(int(percentage_complete)) def cancel_copy(self): """Slot for the cancel command on the progress dialog. The must_run variable of the copyWorker class is set to False to terminate the copy. Input: None Output: None""" self.copyWorker.must_run = False self.copyButton.setEnabled(True) def statusbar_msg(self, msg): """Update the statusbar on the bottom of the screen. Input: msg : string - Message that you would like displayed on the form. Output: None """ self.statusbar.clearMessage() self.statusbar.showMessage(msg) def destination_chooser(self): """Show folder chooser dialog and update lblDestPath with path selected. Input: None Output: None""" dialog = QFileDialog() dialog.setFileMode(QFileDialog.Directory) dialog.setOption(QFileDialog.ShowDirsOnly) dialog.exec_() self.lblDestPath.setEnabled(True) self.lblDestPath.setText(os.path.abspath(dialog.directory().absolutePath())) self.update_table_view() self.copyButton.setEnabled(True) def about(self): """Popup a box with about message. Input: None Output: None""" QMessageBox.about(self, "About MClub Mover", """This program is designed to help make the process of copying \ files from multiple directories much easier and simpler.\n This software is provided as is with absolutely no warranties.""", WindowModility=True)