def restart_add_sessions_thread(self): self.reset_add_thread = True if not hasattr(self, 'repeat_thread_active'): return while self.repeat_thread_active: time.sleep(0.1) self.RepeatAddSessionsThread.setTerminationEnabled(True) self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start")
def run(self, directory): # function that runs klustakwik """This method runs when the Batch-TINT button is pressed on the GUI, and commences the analysis""" self.batch_tint = True self.klustabtn.setText('Stop') self.klustabtn.setToolTip('Click to stop Batch-Tint.') # defining the tool tip for the start button self.klustabtn.clicked.disconnect() self.klustabtn.clicked.connect(self.stopBatch) # self.BatchTintThread = QtCore.QThread() self.BatchTintThread.start() self.BatchTintWorker = Worker(runGUI, self, self.settingsWindow, directory) self.BatchTintWorker.moveToThread(self.BatchTintThread) self.BatchTintWorker.start.emit("start")
def Convert(self): self.choice = None # self.current_session = None self.current_subdirectory = None self.convert_button.setText('Stop Conversion') self.convert_button.setToolTip('Click to stop the conversion.') # defining the tool tip for the start button self.convert_button.clicked.disconnect() self.convert_button.clicked.connect(self.StopConversion) self.conversion = True self.position_overwritten = False # start conversion threads self.convert_thread.start() self.convert_thread_worker = Worker(self.convert_queue) self.convert_thread_worker.moveToThread(self.convert_thread) self.convert_thread_worker.start.emit("start")
def home(self): # defines the home function (the main window) try: # attempts to open previous directory catches error if file not found # No saved directory's need to create file with open(self.directory_settings, 'r+') as filename: # opens the defined file directory_data = json.load(filename) # loads the directory data from file if os.path.exists(directory_data['directory']): current_directory_name = directory_data['directory'] # defines the data else: current_directory_name = 'No Directory Currently Chosen!' # states that no directory was chosen except FileNotFoundError: # runs if file not found with open(self.directory_settings, 'w') as filename: # opens a file current_directory_name = 'No Directory Currently Chosen!' # states that no directory was chosen directory_data = {'directory': current_directory_name} # creates a dictionary json.dump(directory_data, filename) # writes the dictionary to the file # ------buttons ------------------------------------------ quitbtn = QtWidgets.QPushButton('Quit', self) # making a quit button quitbtn.clicked.connect(self.close_app) # defining the quit button functionality (once pressed) quitbtn.setShortcut("Ctrl+Q") # creates shortcut for the quit button quitbtn.setToolTip('Click to quit Batch-Tint!') self.setbtn = QtWidgets.QPushButton('Klusta Settings') # Creates the settings pushbutton self.setbtn.setToolTip('Define the settings that KlustaKwik will use.') self.klustabtn = QtWidgets.QPushButton('Run', self) # creates the batch-klusta pushbutton self.klustabtn.setToolTip('Click to perform batch analysis via Tint and KlustaKwik!') self.smtpbtn = QtWidgets.QPushButton('SMTP Settings', self) self.smtpbtn.setToolTip("Click to change the SMTP settings for e-mail notifications.") self.choose_dir = QtWidgets.QPushButton('Choose Directory', self) # creates the choose directory pushbutton self.current_directory = QtWidgets.QLineEdit() # creates a line edit to display the chosen directory (current) self.current_directory.textChanged.connect(self.change_directory) self.current_directory.setText(current_directory_name) # sets the text to the current directory self.current_directory.setAlignment(QtCore.Qt.AlignHCenter) # centers the text self.current_directory.setToolTip('The current directory that Batch-Tint will analyze.') # defines an attribute to exchange info between classes/modules self.current_directory_name = current_directory_name # defines the button functionality once pressed self.klustabtn.clicked.connect(lambda: self.run(self.current_directory_name)) # ------------------------------------ check box ------------------------------------------------ self.nonbatch_check = QtWidgets.QCheckBox('Non-Batch?') self.nonbatch_check.setToolTip("Check this if you don't want to run batch. This means you will choose\n" "the folder that directly contains all the session files (.set, .pos, .N, etc.).") self.silent_cb = QtWidgets.QCheckBox('Run Silently') self.silent_cb.setToolTip("Check if you want Tint to run in the background.") # ---------------- queue widgets -------------------------------------------------- self.directory_queue = QtWidgets.QTreeWidget() self.directory_queue.headerItem().setText(0, "Axona Sessions:") self.directory_queue.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) directory_queue_label = QtWidgets.QLabel('Queue: ') self.up_btn = QtWidgets.QPushButton("Move Up", self) self.up_btn.setToolTip("Clcik this button to move selected directories up on the queue!") self.up_btn.clicked.connect(lambda: self.moveQueue('up')) self.down_btn = QtWidgets.QPushButton("Move Down", self) self.down_btn.setToolTip("Clcik this button to move selected directories down on the queue!") self.down_btn.clicked.connect(lambda: self.moveQueue('down')) queue_btn_layout = QtWidgets.QVBoxLayout() queue_btn_layout.addWidget(self.up_btn) queue_btn_layout.addWidget(self.down_btn) queue_layout = QtWidgets.QVBoxLayout() queue_layout.addWidget(directory_queue_label) queue_layout.addWidget(self.directory_queue) queue_and_btn_layout = QtWidgets.QHBoxLayout() queue_and_btn_layout.addLayout(queue_layout) queue_and_btn_layout.addLayout(queue_btn_layout) # ------------------------ multithreading widgets ------------------------------------- Multithread_l = QtWidgets.QLabel('Simultaneous Tetrodes (#):') Multithread_l.setToolTip('Input the number of tetrodes you want to analyze simultaneously') self.numThreads = QtWidgets.QLineEdit() Multi_layout = QtWidgets.QHBoxLayout() # for order in [self.multithread_cb, core_num_l, self.core_num, Multithread_l, self.numThreads]: for order in [Multithread_l, self.numThreads]: if 'Layout' in order.__str__(): Multi_layout.addLayout(order) else: Multi_layout.addWidget(order, 0, QtCore.Qt.AlignCenter) # ----- append cut -------------------- append_cut_label = QtWidgets.QLabel("Append Cut:") self.append_cut = QtWidgets.QLineEdit() self.append_cut.setText(defaultAppend) self.append_cut.textChanged.connect(self.change_append) append_cut_layout = QtWidgets.QHBoxLayout() append_cut_layout.addWidget(append_cut_label) append_cut_layout.addWidget(self.append_cut) parameter_layout = QtWidgets.QHBoxLayout() parameter_layout.addStretch(1) parameter_layout.addWidget(self.nonbatch_check) parameter_layout.addStretch(1) parameter_layout.addWidget(self.silent_cb) parameter_layout.addStretch(1) parameter_layout.addLayout(Multi_layout) parameter_layout.addStretch(1) parameter_layout.addLayout(append_cut_layout) parameter_layout.addStretch(1) try: with open(self.settings_fname, 'r+') as filename: settings = json.load(filename) self.numThreads.setText(str(settings['NumThreads'])) if settings['Silent'] == 1: self.silent_cb.toggle() if settings['nonbatch'] == 1: self.nonbatch_check.toggle() except FileNotFoundError: self.silent_cb.toggle() self.numThreads.setText('1') self.get_non_batch() # ------------- Log Box ------------------------- self.Log = QtWidgets.QTextEdit() log_label = QtWidgets.QLabel('Log: ') log_lay = QtWidgets.QVBoxLayout() log_lay.addWidget(log_label, 0, QtCore.Qt.AlignTop) log_lay.addWidget(self.Log) # ------------------------------------ version information ------------------------------------------------- # creates a label with that information vers_label = QtWidgets.QLabel("BatchTINT V3.1.0") # ------------------- page layout ---------------------------------------- layout = QtWidgets.QVBoxLayout() # setting the layout layout1 = QtWidgets.QHBoxLayout() # setting layout for the directory options layout1.addWidget(self.choose_dir) # adding widgets to the first tab layout1.addWidget(self.current_directory) btn_order = [self.klustabtn, self.setbtn, self.smtpbtn, quitbtn] # defining button order (left to right) btn_layout = QtWidgets.QHBoxLayout() # creating a widget to align the buttons for butn in btn_order: # adds the buttons in the proper order btn_layout.addWidget(butn) layout_order = [layout1, parameter_layout, queue_and_btn_layout, log_lay, btn_layout] layout.addStretch(1) # adds the widgets/layouts according to the order for order in layout_order: if 'Layout' in order.__str__(): layout.addLayout(order) layout.addStretch(1) else: layout.addWidget(order, 0, QtCore.Qt.AlignCenter) layout.addStretch(1) layout.addStretch(1) # adds stretch to put the version info at the bottom layout.addWidget(vers_label) # adds the date modification/version number self.setLayout(layout) # sets the widget to the one we defined center(self) # centers the widget on the screen # if self.current_directory_name != 'No Directory Currently Chosen!': # starting adding any existing sessions in a different thread # self.RepeatAddSessionsThread = QtCore.QThread(self) self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start") self.show() # shows the widget
class Window(QtWidgets.QWidget): # defines the window class (main window) def __init__(self): # initializes the main window super(Window, self).__init__() background(self) # acquires some features from the background function we defined earlier self.setWindowTitle("BatchTINT - Main Window") # sets the title of the window self.numCores = str(os.cpu_count()) # initializing the number of cores the users CPU has self.settingsWindow = None self.RepeatAddSessionsThread = QtCore.QThread(self) self.BatchTintThread = QtCore.QThread() self.reset_add_thread = False self.repeat_thread_active = False self.append_changed = False self.current_session = '' self.current_subdirectory = '' self.LogAppend = Communicate() self.LogAppend.myGUI_signal_str.connect(self.AppendLog) self.LogError = Communicate() self.LogError.myGUI_signal_str.connect(self.raiseError) self.RemoveQueueItem = Communicate() self.RemoveQueueItem.myGUI_signal_str.connect(self.takeTopLevel) self.RemoveSessionItem = Communicate() self.RemoveSessionItem.myGUI_signal_str.connect(self.takeChild) self.RemoveSessionData = Communicate() self.RemoveSessionData.myGUI_signal_str.connect(self.takeChildData) self.RemoveChildItem = Communicate() self.RemoveChildItem.myGUI_signal_QTreeWidgetItem.connect(self.removeChild) self.adding_session = True self.reordering_queue = False self.modifying_list = False self.choice = None self.home() # runs the home function def home(self): # defines the home function (the main window) try: # attempts to open previous directory catches error if file not found # No saved directory's need to create file with open(self.directory_settings, 'r+') as filename: # opens the defined file directory_data = json.load(filename) # loads the directory data from file if os.path.exists(directory_data['directory']): current_directory_name = directory_data['directory'] # defines the data else: current_directory_name = 'No Directory Currently Chosen!' # states that no directory was chosen except FileNotFoundError: # runs if file not found with open(self.directory_settings, 'w') as filename: # opens a file current_directory_name = 'No Directory Currently Chosen!' # states that no directory was chosen directory_data = {'directory': current_directory_name} # creates a dictionary json.dump(directory_data, filename) # writes the dictionary to the file # ------buttons ------------------------------------------ quitbtn = QtWidgets.QPushButton('Quit', self) # making a quit button quitbtn.clicked.connect(self.close_app) # defining the quit button functionality (once pressed) quitbtn.setShortcut("Ctrl+Q") # creates shortcut for the quit button quitbtn.setToolTip('Click to quit Batch-Tint!') self.setbtn = QtWidgets.QPushButton('Klusta Settings') # Creates the settings pushbutton self.setbtn.setToolTip('Define the settings that KlustaKwik will use.') self.klustabtn = QtWidgets.QPushButton('Run', self) # creates the batch-klusta pushbutton self.klustabtn.setToolTip('Click to perform batch analysis via Tint and KlustaKwik!') self.smtpbtn = QtWidgets.QPushButton('SMTP Settings', self) self.smtpbtn.setToolTip("Click to change the SMTP settings for e-mail notifications.") self.choose_dir = QtWidgets.QPushButton('Choose Directory', self) # creates the choose directory pushbutton self.current_directory = QtWidgets.QLineEdit() # creates a line edit to display the chosen directory (current) self.current_directory.textChanged.connect(self.change_directory) self.current_directory.setText(current_directory_name) # sets the text to the current directory self.current_directory.setAlignment(QtCore.Qt.AlignHCenter) # centers the text self.current_directory.setToolTip('The current directory that Batch-Tint will analyze.') # defines an attribute to exchange info between classes/modules self.current_directory_name = current_directory_name # defines the button functionality once pressed self.klustabtn.clicked.connect(lambda: self.run(self.current_directory_name)) # ------------------------------------ check box ------------------------------------------------ self.nonbatch_check = QtWidgets.QCheckBox('Non-Batch?') self.nonbatch_check.setToolTip("Check this if you don't want to run batch. This means you will choose\n" "the folder that directly contains all the session files (.set, .pos, .N, etc.).") self.silent_cb = QtWidgets.QCheckBox('Run Silently') self.silent_cb.setToolTip("Check if you want Tint to run in the background.") # ---------------- queue widgets -------------------------------------------------- self.directory_queue = QtWidgets.QTreeWidget() self.directory_queue.headerItem().setText(0, "Axona Sessions:") self.directory_queue.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection) directory_queue_label = QtWidgets.QLabel('Queue: ') self.up_btn = QtWidgets.QPushButton("Move Up", self) self.up_btn.setToolTip("Clcik this button to move selected directories up on the queue!") self.up_btn.clicked.connect(lambda: self.moveQueue('up')) self.down_btn = QtWidgets.QPushButton("Move Down", self) self.down_btn.setToolTip("Clcik this button to move selected directories down on the queue!") self.down_btn.clicked.connect(lambda: self.moveQueue('down')) queue_btn_layout = QtWidgets.QVBoxLayout() queue_btn_layout.addWidget(self.up_btn) queue_btn_layout.addWidget(self.down_btn) queue_layout = QtWidgets.QVBoxLayout() queue_layout.addWidget(directory_queue_label) queue_layout.addWidget(self.directory_queue) queue_and_btn_layout = QtWidgets.QHBoxLayout() queue_and_btn_layout.addLayout(queue_layout) queue_and_btn_layout.addLayout(queue_btn_layout) # ------------------------ multithreading widgets ------------------------------------- Multithread_l = QtWidgets.QLabel('Simultaneous Tetrodes (#):') Multithread_l.setToolTip('Input the number of tetrodes you want to analyze simultaneously') self.numThreads = QtWidgets.QLineEdit() Multi_layout = QtWidgets.QHBoxLayout() # for order in [self.multithread_cb, core_num_l, self.core_num, Multithread_l, self.numThreads]: for order in [Multithread_l, self.numThreads]: if 'Layout' in order.__str__(): Multi_layout.addLayout(order) else: Multi_layout.addWidget(order, 0, QtCore.Qt.AlignCenter) # ----- append cut -------------------- append_cut_label = QtWidgets.QLabel("Append Cut:") self.append_cut = QtWidgets.QLineEdit() self.append_cut.setText(defaultAppend) self.append_cut.textChanged.connect(self.change_append) append_cut_layout = QtWidgets.QHBoxLayout() append_cut_layout.addWidget(append_cut_label) append_cut_layout.addWidget(self.append_cut) parameter_layout = QtWidgets.QHBoxLayout() parameter_layout.addStretch(1) parameter_layout.addWidget(self.nonbatch_check) parameter_layout.addStretch(1) parameter_layout.addWidget(self.silent_cb) parameter_layout.addStretch(1) parameter_layout.addLayout(Multi_layout) parameter_layout.addStretch(1) parameter_layout.addLayout(append_cut_layout) parameter_layout.addStretch(1) try: with open(self.settings_fname, 'r+') as filename: settings = json.load(filename) self.numThreads.setText(str(settings['NumThreads'])) if settings['Silent'] == 1: self.silent_cb.toggle() if settings['nonbatch'] == 1: self.nonbatch_check.toggle() except FileNotFoundError: self.silent_cb.toggle() self.numThreads.setText('1') self.get_non_batch() # ------------- Log Box ------------------------- self.Log = QtWidgets.QTextEdit() log_label = QtWidgets.QLabel('Log: ') log_lay = QtWidgets.QVBoxLayout() log_lay.addWidget(log_label, 0, QtCore.Qt.AlignTop) log_lay.addWidget(self.Log) # ------------------------------------ version information ------------------------------------------------- # creates a label with that information vers_label = QtWidgets.QLabel("BatchTINT V3.1.0") # ------------------- page layout ---------------------------------------- layout = QtWidgets.QVBoxLayout() # setting the layout layout1 = QtWidgets.QHBoxLayout() # setting layout for the directory options layout1.addWidget(self.choose_dir) # adding widgets to the first tab layout1.addWidget(self.current_directory) btn_order = [self.klustabtn, self.setbtn, self.smtpbtn, quitbtn] # defining button order (left to right) btn_layout = QtWidgets.QHBoxLayout() # creating a widget to align the buttons for butn in btn_order: # adds the buttons in the proper order btn_layout.addWidget(butn) layout_order = [layout1, parameter_layout, queue_and_btn_layout, log_lay, btn_layout] layout.addStretch(1) # adds the widgets/layouts according to the order for order in layout_order: if 'Layout' in order.__str__(): layout.addLayout(order) layout.addStretch(1) else: layout.addWidget(order, 0, QtCore.Qt.AlignCenter) layout.addStretch(1) layout.addStretch(1) # adds stretch to put the version info at the bottom layout.addWidget(vers_label) # adds the date modification/version number self.setLayout(layout) # sets the widget to the one we defined center(self) # centers the widget on the screen # if self.current_directory_name != 'No Directory Currently Chosen!': # starting adding any existing sessions in a different thread # self.RepeatAddSessionsThread = QtCore.QThread(self) self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start") self.show() # shows the widget def run(self, directory): # function that runs klustakwik """This method runs when the Batch-TINT button is pressed on the GUI, and commences the analysis""" self.batch_tint = True self.klustabtn.setText('Stop') self.klustabtn.setToolTip('Click to stop Batch-Tint.') # defining the tool tip for the start button self.klustabtn.clicked.disconnect() self.klustabtn.clicked.connect(self.stopBatch) # self.BatchTintThread = QtCore.QThread() self.BatchTintThread.start() self.BatchTintWorker = Worker(runGUI, self, self.settingsWindow, directory) self.BatchTintWorker.moveToThread(self.BatchTintThread) self.BatchTintWorker.start.emit("start") def close_app(self): # pop up window that asks if you really want to exit the app ------------------------------------------------ choice = QtWidgets.QMessageBox.question(self, "Quitting BatchTINT", "Do you really want to exit?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if choice == QtWidgets.QMessageBox.Yes: sys.exit() # tells the app to quit else: pass def raiseError(self, error_val): """raises an error window given certain errors from an emitted signal""" if 'ManyFet' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No Chosen Directory: BatchTINT", "You have chosen more than four features,\n" "clustering will take a long time.\n" "Do you realy want to continue?", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) elif 'NoDir' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No Chosen Directory: BatchTINT", "You have not chosen a directory,\n" "please choose one to continue!", QtWidgets.QMessageBox.Ok) elif 'GoogleDir' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "Google Drive Directory: BatchTINT", "You have not chosen a directory within Google Drive,\n" "be aware that during testing we have experienced\n" "permissions errors while using Google Drive directories\n" "that would result in BatchTINTV3 not being able to move\n" "the files to the Processed folder (and stopping the GUI),\n" "do you want to continue?", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) elif 'NoSet' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No .Set Files!", "You have chosen a directory that has no .Set files!\n" "Please choose a different directory!", QtWidgets.QMessageBox.Ok) elif 'InvDirBatch' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "Invalid Directory!", "In 'Batch Mode' you need to choose a directory\n" "with subdirectories that contain all your Tint\n" "files. Press Abort and choose new file, or if you\n" "plan on adding folders to the chosen directory press\n" "continue.", QtWidgets.QMessageBox.Abort | QtWidgets.QMessageBox.Ok) elif 'InvDirNonBatch' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "Invalid Directory!", "In 'Non-Batch Mode' you need to choose a directory\n" "that contain all your Tint files.\n", QtWidgets.QMessageBox.Ok) def AppendLog(self, message): """ A function that will append the Log field of the main window (mainly used as a slot for a custom pyqt signal) """ if '#' in message: message = message.split('#') color = message[-1].lower() message = message[0] message = '<span style="color:%s">%s</span>' % (color, message) self.Log.append(message) def stopBatch(self): enableParameters(self) self.klustabtn.clicked.connect(lambda: self.run(self.current_directory_name)) self.BatchTintThread.terminate() self.LogAppend.myGUI_signal_str.emit( '[%s %s]: BatchTint stopped!' % (str(datetime.datetime.now().date()), str(datetime.datetime.now().time())[ :8])) self.batch_tint = False self.klustabtn.setText('Run') self.klustabtn.setToolTip( 'Click to perform batch analysis via Tint and KlustaKwik!') # defining the tool tip for the start button def change_directory(self): """ Whenever directory is changed, clear the directory queue """ self.current_directory_name = self.current_directory.text() try: self.directory_queue.clear() except AttributeError: pass self.restart_add_sessions_thread() def change_append(self): self.change_append_time = time.time() self.append_changed = True def restart_add_sessions_thread(self): self.reset_add_thread = True if not hasattr(self, 'repeat_thread_active'): return while self.repeat_thread_active: time.sleep(0.1) self.RepeatAddSessionsThread.setTerminationEnabled(True) self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start") def moveQueue(self, direction): # get all the queue items while self.adding_session: time.sleep(0.1) if self.reordering_queue: self.reordering_queue = False self.reordering_queue = True item_count = self.directory_queue.topLevelItemCount() queue_items = {} for item_index in range(item_count): queue_items[item_index] = self.directory_queue.topLevelItem(item_index) # get selected options and their locations selected_items = self.directory_queue.selectedItems() selected_items_copy = [] [selected_items_copy.append(item.clone()) for item in selected_items] add_to_new_queue = list(queue_items.values()) if not selected_items: # skips when there are no items selected return new_queue_order = {} # find if consecutive indices from 0 on are selected as these won't move any further up indices = find_keys(queue_items, selected_items) consecutive_indices = find_consec(indices) # this will spit a list of lists, these nested lists will have consecutive indices within them # i.e. if indices 0, 1 and 3 were chosen it would have [[0, 1], [3]] if 'up' in direction: # first add the selected items to their new spots for consecutive in consecutive_indices: if 0 in consecutive: # these items can't move up any further for index in consecutive: new_item = queue_items[index].clone() new_queue_order[index] = new_item else: for index in consecutive: # move these up the list (decrease in index value since 0 is the top of the list) new_item = queue_items[index].clone() new_queue_order[index - 1] = new_item for key, val in new_queue_order.items(): for index, item in enumerate(add_to_new_queue): if val.data(0, 0) == item.data(0, 0): add_to_new_queue.remove(item) # remove item from the list break _ = list(new_queue_order.keys()) # a list of already moved items not_in_reordered = False # place the unplaced items that aren't moving for static_index, static_value in queue_items.items(): # print(static_value.data(0,0)) # place the unplaced items if static_index in _: continue for queue_item in new_queue_order.values(): not_in_reordered = True if static_value.data(0, 0) == queue_item.data(0, 0): # don't re-add the one that is going to be moved not_in_reordered = False break if not_in_reordered: for value in add_to_new_queue: if static_value.data(0, 0) == value.data(0, 0): add_to_new_queue.remove(value) # remove item from the list break new_queue_order[static_index] = static_value.clone() elif 'down' in direction: # first add the selected items to their new spots for consecutive in consecutive_indices: if (item_count - 1) in consecutive: # these items can't move down any further for index in consecutive: new_item = queue_items[index].clone() # new_item.setSelected(True) new_queue_order[index] = new_item else: for index in consecutive: # move these down the list (increase in index value since 0 is the top of the list) new_item = queue_items[index].clone() # new_item.setSelected(True) new_queue_order[index + 1] = new_item for key, val in new_queue_order.items(): for index, item in enumerate(add_to_new_queue): if val.data(0, 0) == item.data(0, 0): add_to_new_queue.remove(item) break _ = list(new_queue_order.keys()) # a list of already moved items not_in_reordered = False # place the unplaced items that aren't moving for static_index, static_value in queue_items.items(): if static_index in _: continue for queue_item in new_queue_order.values(): not_in_reordered = True if static_value.data(0, 0) == queue_item.data(0, 0): # don't re-add the one that is going to be moved not_in_reordered = False break if not_in_reordered: for value in add_to_new_queue: if static_value.data(0, 0) == value.data(0, 0): add_to_new_queue.remove(value) # remove item from the list break new_queue_order[static_index] = static_value.clone() # add the remaining items indices_needed = [index for index in range(item_count) if index not in list(new_queue_order.keys())] for index, displaced_item in enumerate(add_to_new_queue): new_queue_order[indices_needed[index]] = displaced_item.clone() self.directory_queue.clear() # clears the list for key, value in sorted(new_queue_order.items()): self.directory_queue.addTopLevelItem(value) # reselect the items iterator = QtWidgets.QTreeWidgetItemIterator(self.directory_queue) while iterator.value(): for selected_item in selected_items_copy: item = iterator.value() if item.data(0, 0) == selected_item.data(0, 0): item.setSelected(True) break iterator += 1 self.reordering_queue = False def takeTopLevel(self, item_count): item_count = int(item_count) self.directory_queue.takeTopLevelItem(item_count) self.top_level_taken = True def setChild(self, child_count): self.child_session = self.directory_item.child(int(child_count)) self.child_set = True def takeChild(self, child_count): self.child_session = self.directory_item.takeChild(int(child_count)) self.child_taken = True # return child_session def takeChildData(self, child_count): self.child_session = self.directory_item.takeChild(int(child_count)).data(0, 0) self.child_data_taken = True def removeChild(self, QTreeWidgetItem): root = self.directory_queue.invisibleRootItem() (QTreeWidgetItem.parent() or root).removeChild(QTreeWidgetItem) self.child_removed = True def get_non_batch(self): if self.nonbatch_check.isChecked(): self.nonbatch = 1 else: self.nonbatch = 0 def getMainWindowSettings(self): settings = {} if self.silent_cb.isChecked(): settings['Silent'] = 1 else: settings['Silent'] = 0 if self.nonbatch_check.isChecked(): settings['nonbatch'] = 1 self.nonbatch = 1 else: settings['nonbatch'] = 0 self.nonbatch = 0 settings['NumThreads'] = self.numThreads.text() settings['Cores'] = str(os.cpu_count()) return settings
def home(self): # defines the home function (the main window) # read any previous directories chosen so we don't have to try: # attempts to open previous directory catches error if file not found # No saved directory's need to create file with open(self.directory_settings, 'r+') as filename: # opens the defined file directory_data = json.load(filename) # loads the directory data from file if os.path.exists(directory_data['directory']): current_directory_name = directory_data['directory'] # defines the data else: current_directory_name = default_filename # states that no directory was chosen except FileNotFoundError: # runs if file not found with open(self.directory_settings, 'w') as filename: # opens a file current_directory_name = default_filename # states that no directory was chosen directory_data = {'directory': current_directory_name} # creates a dictionary json.dump(directory_data, filename) # writes the dictionary to the file # ------ buttons + widgets ----------------------------- quit_btn = QtWidgets.QPushButton("Quit", self) quit_btn.clicked.connect(self.close_app) quit_btn.setShortcut("Ctrl+Q") quit_btn.setToolTip('Click to quit (or press Ctrl+Q)') self.convert_button = QtWidgets.QPushButton('Convert', self) self.convert_button.clicked.connect(self.Convert) self.convert_button.setToolTip('Click to start the conversion.') self.batch_tint_settings_window = None self.batch_tint_settings_button = QtWidgets.QPushButton("Batch Tint Settings") self.batch_tint_settings_button.clicked.connect(self.open_batch_tint_settings) btn_layout = QtWidgets.QHBoxLayout() button_order = [self.convert_button, self.batch_tint_settings_button, quit_btn] for button in button_order: btn_layout.addWidget(button) # Version information ------------------------------------------- vers_label = QtWidgets.QLabel("%s V1.0.3" % (project_name, )) # ------------------ widget layouts ---------------- self.choose_directory_btn = QtWidgets.QPushButton('Choose Directory', self) self.choose_directory_btn.clicked.connect(self.new_directory) # the label that states that the line-edit corresponds to the current directory directory_label = QtWidgets.QLabel('Current Directory') directory_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) # the line-edit that displays the current directory self.directory_edit = QtWidgets.QLineEdit() self.directory_edit.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) # aligning the text self.directory_edit.setText(current_directory_name) # default text # updates the directory every time the text changes self.directory_edit.textChanged.connect(self.changed_directory) self.batch_tint_checkbox = QtWidgets.QCheckBox("Batch Tint") self.batch_tint_checkbox.toggle() self.move_converted_checkbox = QtWidgets.QCheckBox("Move Converted") self.move_converted_checkbox.toggle() # creating the layout for the text + line-edit so that they are aligned appropriately current_directory_layout = QtWidgets.QHBoxLayout() current_directory_layout.addWidget(directory_label) current_directory_layout.addWidget(self.directory_edit) current_directory_layout.addWidget(self.batch_tint_checkbox) current_directory_layout.addWidget(self.move_converted_checkbox) # creating a layout with the line-edit/text + the button so that they are all together directory_layout = QtWidgets.QHBoxLayout() directory_layout.addWidget(self.choose_directory_btn) directory_layout.addLayout(current_directory_layout) # creates the queue of recording sessions to convert self.recording_queue = QtWidgets.QTreeWidget() self.recording_queue.headerItem().setText(0, "Recording Session:") recording_queue_label = QtWidgets.QLabel("Conversion Queue:") recording_queue_label.setFont(QtGui.QFont("Arial", 10, weight=QtGui.QFont.Bold)) recording_queue_layout = QtWidgets.QVBoxLayout() recording_queue_layout.addWidget(recording_queue_label) recording_queue_layout.addWidget(self.recording_queue) # adding the layout for the log self.log = QtWidgets.QTextEdit() log_label = QtWidgets.QLabel('Log:') log_label.setFont(QtGui.QFont("Arial", 10, weight=QtGui.QFont.Bold)) log_layout = QtWidgets.QVBoxLayout() log_layout.addWidget(log_label) log_layout.addWidget(self.log) # adding the thresholding portion fo the layout threshold_label = QtWidgets.QLabel('Threshold(SD\'s)') self.threshold = QtWidgets.QLineEdit() self.threshold.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.threshold.setText(str(default_threshold)) self.threshold.setToolTip("This will determine the standard deviations away from the baseline value " + "that you want to use for the thresholding") # check if you want to perform a DC block on the EEG and EGF data self.dc_blocker = QtWidgets.QCheckBox("DC Blocking Filter") self.dc_blocker.toggle() # set the default to on threshold_layout = QtWidgets.QHBoxLayout() for widget in [threshold_label, self.threshold]: threshold_layout.addWidget(widget) # extra parameters layout parameters_layout = QtWidgets.QHBoxLayout() for parameter in [threshold_layout, self.dc_blocker]: if 'Layout' in parameter.__str__(): parameters_layout.addLayout(parameter) else: parameters_layout.addWidget(parameter) # ------------- layout ------------------------------ layout = QtWidgets.QVBoxLayout() layout_order = [directory_layout, recording_queue_layout, log_layout, parameters_layout, btn_layout] for order in layout_order: if 'Layout' in order.__str__(): layout.addLayout(order) layout.addStretch(1) else: layout.addWidget(order, 0, QtCore.Qt.AlignCenter) layout.addStretch(1) layout.addStretch(1) # adds stretch to put the version info at the button layout.addWidget(vers_label) # adds the date modification/version number self.setSettings() self.setLayout(layout) center(self) self.set_batch_tint_settings() self.show() # start thread that will search for new files to convert self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start")
class Window(QtWidgets.QWidget): # defines the window class (main window) def __init__(self): # initializes the main window super(Window, self).__init__() background(self) # acquires some features from the background function we defined earlier # sets the title of the window self.setWindowTitle("%s - Main Window" % project_name) # self.current_session = None self.current_subdirectory = None self.directory_changed = False self.modifying_list = False self.reset_add_thread = False self.repeat_thread_active = True self.conversion = False self.choice = None self.file_chosen = False # this signal will append errors/messages to the Log object self.LogAppend = Communicate() self.LogAppend.myGUI_signal.connect(self.AppendLog) # this signal will raise any errors self.LogError = Communicate() self.LogError.myGUI_signal.connect(self.raiseError) # this will remove the top level item from the queue self.RemoveQueueItem = Communicate() self.RemoveQueueItem.myGUI_signal.connect(self.takeTopLevel) self.RemoveSessionItem = Communicate() self.RemoveSessionItem.myGUI_signal.connect(self.takeChild) self.RemoveSessionData = Communicate() self.RemoveSessionData.myGUI_signal.connect(self.takeChildData) self.SetSessionItem = Communicate() self.SetSessionItem.myGUI_signal.connect(self.setChild) self.RemoveChildItem = Communicate() self.RemoveChildItem.myGUI_signal_QTreeWidgetItem.connect(self.removeChild) self.RepeatAddSessionsThread = QtCore.QThread() self.convert_thread = QtCore.QThread() self.home() # runs the home function def home(self): # defines the home function (the main window) # read any previous directories chosen so we don't have to try: # attempts to open previous directory catches error if file not found # No saved directory's need to create file with open(self.directory_settings, 'r+') as filename: # opens the defined file directory_data = json.load(filename) # loads the directory data from file if os.path.exists(directory_data['directory']): current_directory_name = directory_data['directory'] # defines the data else: current_directory_name = default_filename # states that no directory was chosen except FileNotFoundError: # runs if file not found with open(self.directory_settings, 'w') as filename: # opens a file current_directory_name = default_filename # states that no directory was chosen directory_data = {'directory': current_directory_name} # creates a dictionary json.dump(directory_data, filename) # writes the dictionary to the file # ------ buttons + widgets ----------------------------- quit_btn = QtWidgets.QPushButton("Quit", self) quit_btn.clicked.connect(self.close_app) quit_btn.setShortcut("Ctrl+Q") quit_btn.setToolTip('Click to quit (or press Ctrl+Q)') self.convert_button = QtWidgets.QPushButton('Convert', self) self.convert_button.clicked.connect(self.Convert) self.convert_button.setToolTip('Click to start the conversion.') self.batch_tint_settings_window = None self.batch_tint_settings_button = QtWidgets.QPushButton("Batch Tint Settings") self.batch_tint_settings_button.clicked.connect(self.open_batch_tint_settings) btn_layout = QtWidgets.QHBoxLayout() button_order = [self.convert_button, self.batch_tint_settings_button, quit_btn] for button in button_order: btn_layout.addWidget(button) # Version information ------------------------------------------- vers_label = QtWidgets.QLabel("%s V1.0.3" % (project_name, )) # ------------------ widget layouts ---------------- self.choose_directory_btn = QtWidgets.QPushButton('Choose Directory', self) self.choose_directory_btn.clicked.connect(self.new_directory) # the label that states that the line-edit corresponds to the current directory directory_label = QtWidgets.QLabel('Current Directory') directory_label.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter) # the line-edit that displays the current directory self.directory_edit = QtWidgets.QLineEdit() self.directory_edit.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) # aligning the text self.directory_edit.setText(current_directory_name) # default text # updates the directory every time the text changes self.directory_edit.textChanged.connect(self.changed_directory) self.batch_tint_checkbox = QtWidgets.QCheckBox("Batch Tint") self.batch_tint_checkbox.toggle() self.move_converted_checkbox = QtWidgets.QCheckBox("Move Converted") self.move_converted_checkbox.toggle() # creating the layout for the text + line-edit so that they are aligned appropriately current_directory_layout = QtWidgets.QHBoxLayout() current_directory_layout.addWidget(directory_label) current_directory_layout.addWidget(self.directory_edit) current_directory_layout.addWidget(self.batch_tint_checkbox) current_directory_layout.addWidget(self.move_converted_checkbox) # creating a layout with the line-edit/text + the button so that they are all together directory_layout = QtWidgets.QHBoxLayout() directory_layout.addWidget(self.choose_directory_btn) directory_layout.addLayout(current_directory_layout) # creates the queue of recording sessions to convert self.recording_queue = QtWidgets.QTreeWidget() self.recording_queue.headerItem().setText(0, "Recording Session:") recording_queue_label = QtWidgets.QLabel("Conversion Queue:") recording_queue_label.setFont(QtGui.QFont("Arial", 10, weight=QtGui.QFont.Bold)) recording_queue_layout = QtWidgets.QVBoxLayout() recording_queue_layout.addWidget(recording_queue_label) recording_queue_layout.addWidget(self.recording_queue) # adding the layout for the log self.log = QtWidgets.QTextEdit() log_label = QtWidgets.QLabel('Log:') log_label.setFont(QtGui.QFont("Arial", 10, weight=QtGui.QFont.Bold)) log_layout = QtWidgets.QVBoxLayout() log_layout.addWidget(log_label) log_layout.addWidget(self.log) # adding the thresholding portion fo the layout threshold_label = QtWidgets.QLabel('Threshold(SD\'s)') self.threshold = QtWidgets.QLineEdit() self.threshold.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) self.threshold.setText(str(default_threshold)) self.threshold.setToolTip("This will determine the standard deviations away from the baseline value " + "that you want to use for the thresholding") # check if you want to perform a DC block on the EEG and EGF data self.dc_blocker = QtWidgets.QCheckBox("DC Blocking Filter") self.dc_blocker.toggle() # set the default to on threshold_layout = QtWidgets.QHBoxLayout() for widget in [threshold_label, self.threshold]: threshold_layout.addWidget(widget) # extra parameters layout parameters_layout = QtWidgets.QHBoxLayout() for parameter in [threshold_layout, self.dc_blocker]: if 'Layout' in parameter.__str__(): parameters_layout.addLayout(parameter) else: parameters_layout.addWidget(parameter) # ------------- layout ------------------------------ layout = QtWidgets.QVBoxLayout() layout_order = [directory_layout, recording_queue_layout, log_layout, parameters_layout, btn_layout] for order in layout_order: if 'Layout' in order.__str__(): layout.addLayout(order) layout.addStretch(1) else: layout.addWidget(order, 0, QtCore.Qt.AlignCenter) layout.addStretch(1) layout.addStretch(1) # adds stretch to put the version info at the button layout.addWidget(vers_label) # adds the date modification/version number self.setSettings() self.setLayout(layout) center(self) self.set_batch_tint_settings() self.show() # start thread that will search for new files to convert self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start") def setCheckbox(self, widget, value): if widget.isChecked() and not value: # if the checkbox is checked and it isn't supposed to be, untoggle widget.toggle() elif not widget.isChecked and value: # if checkbox isn't checked, and it's supposed to be, toggle widget.toggle() def setValues(self, settings): self.setCheckbox(self.batch_tint_checkbox, settings['batchtint']) self.setCheckbox(self.move_converted_checkbox, settings['move_converted']) self.threshold.setText(str(settings['threshold'])) def setSettings(self): try: with open(self.settings_fname, 'r+') as filename: settings = json.load(filename) except FileNotFoundError: self.setDefaultSettings() with open(self.settings_fname, 'r+') as filename: settings = json.load(filename) try: self.setValues(settings) except KeyError: # re-create settings file, likely you have an outdated version self.setDefaultSettings() self.setValues(settings) def setDefaultSettings(self): settings = {} settings['batchtint'] = default_batchtint settings['move_converted'] = default_move_converted settings['threshold'] = default_threshold with open(self.settings_fname, 'w') as filename: json.dump(settings, filename) def getSettings(self): settings = {} settings['batchtint'] = self.batch_tint_checkbox.isChecked() settings['move_converted'] = self.move_converted_checkbox.isChecked() settings['threshold'] = self.threshold.text() return settings def restart_add_sessions_thread(self): self.reset_add_thread = True if not hasattr(self, 'repeat_thread_active'): return while self.repeat_thread_active: time.sleep(0.1) self.RepeatAddSessionsThread.setTerminationEnabled(True) self.RepeatAddSessionsThread.start() self.RepeatAddSessionsWorker = Worker(RepeatAddSessions, self) self.RepeatAddSessionsWorker.moveToThread(self.RepeatAddSessionsThread) self.RepeatAddSessionsWorker.start.emit("start") def set_batch_tint_settings(self): """This method will be used for the Batch Tint Settings window. It will define the window, as well as raise the window if it is already defined""" if self.batch_tint_settings_window is None: batchtint_filename = os.path.join(self.SETTINGS_DIR, 'batchtint_settings_filename.json') self.batch_tint_settings_window = Settings_Window(settings_fname=batchtint_filename) self.batch_tint_settings_window.backbtn.clicked.connect(lambda: raise_w(self, self.batch_tint_settings_window)) self.batch_tint_settings_window.backbtn2.clicked.connect(lambda: raise_w(self, self.batch_tint_settings_window)) def open_batch_tint_settings(self): if self.batch_tint_settings_window is None: self.set_batch_tint_settings() self.batch_tint_settings_window.raise_window() def changed_directory(self): self.directory_changed = True self.change_directory_time = time.time() # Find the sessions, and populate the conversion queue def AppendLog(self, message): """ A function that will append the Log field of the main window (mainly used as a slot for a custom pyqt signal) """ if '#' in message: message = message.split('#') color = message[-1].lower() message = message[0] message = '<span style="color:%s">%s</span>' % (color, message) self.log.append(message) def raiseError(self, error_val): '''raises an error window given certain errors from an emitted signal''' if 'NoDir' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No Chosen Directory", "You have not chosen a directory,\n" "please choose one to continue!", QtWidgets.QMessageBox.Ok) elif 'NoPos' in error_val: session_pos_filename = error_val[error_val.find('!')+1:] self.choice = QtWidgets.QMessageBox.question(self, "No '.pos' file!", "There '.pos' file for this '.rhd' session:\n" + '%s\n' %session_pos_filename + "was not found. would you like a dummy '.pos' file \n" "to be created for you?\n", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) elif 'NoTintSettings' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No Batch-Tint Settings Directory!", "You have not chosen the settings directory for Batch-Tint,\n" "in the main directory that holds all the Batch-Tint files\n" "there will be a directory entitled 'settings' that holds\n" "all the '.json' files, please choose this folder to continue!", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Abort) while self.choice is None: time.sleep(0.5) if self.choice == QtWidgets.QMessageBox.Ok: self.new_settings_directory() else: return elif 'StillNoTintSettings' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No Batch-Tint Settings Directory!", "You still have not chosen the settings directory for Batch-Tint,\n" "please choose it now.\n", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Abort) while self.choice is None: time.sleep(0.5) if self.choice == QtWidgets.QMessageBox.Ok: self.new_settings_directory() else: return elif 'DefaultTintSettings' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "No Batch-Tint Settings Directory!", "You still have not chosen the settings directory for Batch-Tint,\n" "Do you want to try with the default batch-tint settings?\n", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.Abort) elif 'InvalidTintSettings' in error_val: self.choice = QtWidgets.QMessageBox.question(self, "Invalid Batch-Tint Settings file!", "You chose an invalid Batch-Tint settings directory,\n" "Do you want to choose another directory?\n" "Note: Press Default to use the default Batch-Tint Settings!", QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.Default | QtWidgets.QMessageBox.Abort) if self.choice == QtWidgets.QMessageBox.Yes: self.new_settings_directory() else: return def close_app(self): # pop up window that asks if you really want to exit the app ------------------------------------------------ choice = QtWidgets.QMessageBox.question(self, "Quitting ", "Do you really want to exit?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if choice == QtWidgets.QMessageBox.Yes: sys.exit() # tells the app to quit else: pass def Convert(self): self.choice = None # self.current_session = None self.current_subdirectory = None self.convert_button.setText('Stop Conversion') self.convert_button.setToolTip('Click to stop the conversion.') # defining the tool tip for the start button self.convert_button.clicked.disconnect() self.convert_button.clicked.connect(self.StopConversion) self.conversion = True self.position_overwritten = False # start conversion threads self.convert_thread.start() self.convert_thread_worker = Worker(self.convert_queue) self.convert_thread_worker.moveToThread(self.convert_thread) self.convert_thread_worker.start.emit("start") def convert_queue(self): if default_filename in self.directory_edit.text(): self.LogError.myGUI_signal.emit('NoDir') self.StopConversion() return if self.recording_queue.topLevelItemCount() == 0: pass while self.conversion: self.session_item = self.recording_queue.topLevelItem(0) if not self.session_item: continue else: # check if the path exists sessionpath = os.path.join(self.directory_edit.text(), self.session_item.data(0, 0)) if not os.path.exists(sessionpath): self.top_level_taken = False self.RemoveQueueItem.myGUI_signal.emit(str(0)) while not self.top_level_taken: time.sleep(0.1) continue self.current_subdirectory = sessionpath # overwrite the settings file so it saves these settings for next time self.settings = self.getSettings() with open(self.settings_fname, 'w') as f: json.dump(self.settings, f) # overwrite the directory name with open(self.directory_settings, 'w') as f: json.dump({'directory': self.directory_edit.text()}, f) ConvertSession(self.session_item.data(0, 0), self.settings, self) def StopConversion(self): self.convert_button.setText('Convert') self.convert_button.setToolTip('Click to start the conversion.') # defining the tool tip for the start button self.convert_button.clicked.disconnect() self.convert_button.clicked.connect(self.Convert) # self.convert_thread.quit() self.convert_thread.terminate() self.LogAppend.myGUI_signal.emit( '[%s %s]: Conversion terminated!' % (str(datetime.datetime.now().date()), str(datetime.datetime.now().time())[:8])) self.conversion = False def new_directory(self): """ A function that will be used from the Choose Set popup window that will produce a popup so the user can pick a filename for the .set file """ # prompt user to pick a .set file current_directory_name = QtWidgets.QFileDialog.getExistingDirectory(self, "Select a Directory!") # if no file chosen, skip if current_directory_name == '': return # change the line-edit that contains the directory information self.directory_edit.setText(current_directory_name) def new_file(self): """ this method is no longer necessary, decided to have the user choose the settings directory instead of the file """ cur_file_name, file_ext = QtWidgets.QFileDialog.getOpenFileName(self, "Select your Batch-Tint Settings File!", '', 'Settings Files (*settings.json)') # if no file chosen, skip if cur_file_name == '': return # replace the current .set field in the choose .set window with chosen filename self.batchtintsettings_edit.setText(cur_file_name) self.file_chosen = True def new_settings_directory(self): current_directory_name = QtWidgets.QFileDialog.getExistingDirectory(self, "Select a Directory!") if current_directory_name != '': # replace the current .set field in the choose .set window with chosen filename self.batchtintsettings_edit.setText(current_directory_name) self.SETTINGS_DIR = current_directory_name self.directory_chosen = True def takeTopLevel(self, item_count): item_count = int(item_count) self.recording_queue.takeTopLevelItem(item_count) self.top_level_taken = True def setChild(self, child_count): """ this method will set the self.child_session value to a provided child number of the self.session_item item. :param child_count: :return: """ self.child_session = self.session_item.child(int(child_count)).clone() self.child_set = True def takeChild(self, child_count): self.child_session = self.session_item.takeChild(int(child_count)).clone() self.child_taken = True # return child_session def takeChildData(self, child_count): self.child_session = self.session_item.takeChild(int(child_count)).data(0, 0) self.child_data_taken = True def removeChild(self, QTreeWidgetItem): root = self.recording_queue.invisibleRootItem() (QTreeWidgetItem.parent() or root).removeChild(QTreeWidgetItem) self.child_removed = True
def start(self): """Printing json result of converting.""" self.get_rates() converter = Worker(self.rates, self.amount, self.input_currency, self.output_currency) print(json.dumps(converter.convert(), indent=4))