def _load_files(self, fnames): # if self.ctx.isImage: self.on_close_image() self.statusBar().showMessage('Loading Images') n = len(fnames) progress = QProgressDialog(f"Loading {n} images...", "Cancel", 0, n, self) progress.setWindowModality(Qt.WindowModal) progress.setMinimumDuration(1000) # operation shorter than 1 sec will not open progress dialog files = [] for idx, filename in enumerate(fnames): dcm = get_dicom(filename) files.append(dcm) progress.setValue(idx) if progress.wasCanceled(): break progress.setValue(n) if not files: progress.cancel() if self.fsource=='dir': QMessageBox.information(None, "Info", "No DICOM files in the selected directory.") elif self.fsource=='sample': QMessageBox.information(None, "Info", "No DICOM files in sample directory.") elif self.fsource=='files': QMessageBox.warning(None, "Info", "The specified file is not a valid DICOM file.") return self.ctx.isImage = True self.ctx.dicoms, dc = self.filter_invalid(files) if dc>0: f = 'files' if dc>1 else 'file' QMessageBox.warning(None, "Unsupported format", f"Cannot load {dc} {f}.") self.ctx.total_img = len(self.ctx.dicoms) self.total_lbl.setText(str(self.ctx.total_img)) self.ctx.current_img = 1 self.update_image() self.ctx.app_data.emit_img_loaded(True) self.go_to_slice_sb.setValue(self.ctx.current_img) self.go_to_slice_sb.setMinimum(self.ctx.current_img) self.go_to_slice_sb.setMaximum(self.ctx.total_img) self.get_patient_info() phantom_id = int(not self.patient_info['protocol'].upper() in ['HEAD', 'HEADNECK', 'NECK']) if self.patient_info['protocol'] is not None else 1 self.phantom_cb.setCurrentIndex(phantom_id) self.on_phantom_update(phantom_id) self.info_panel.setInfo(self.patient_info) self.dcmtree_btn.setEnabled(True) self.close_img_btn.setEnabled(True) self.windowing_cb.setEnabled(True) self.sort_btn.setEnabled(True) self.adjust_slices()
def showbarprocess(content): num = int(100000) progress = QProgressDialog() progress.setWindowTitle("Processing ...") progress.setLabelText(content) progress.setCancelButton(None) ##不显示cancel button #progress.setCancelButtonText("") progress.setMinimumDuration(5) progress.setWindowModality(Qt.WindowModal) progress.setRange(0, num) for i in range(num): progress.setValue(i) else: progress.setValue(num) progress.cancel()
def _start(self, type_file, sleep_time, new_file, output_file): progress = QProgressDialog(NAME_PROGRESS_BAR, "", 0, 100, parent=self.window) progress.setWindowModality(Qt.WindowModal) progress.setCancelButton(None) progress.setWindowFlags(progress.windowFlags() & ~Qt.WindowCloseButtonHint) progress.setMinimumDuration(0) thread = Thread(self.window, type_file, new_file, output_file) thread.start() while not thread.isFinished() or progress.value() != 99: loop = QEventLoop() QTimer.singleShot(sleep_time if not thread.isFinished() else 100, loop.quit) loop.exec_() if progress.value() == 99: continue progress.setValue(progress.value() + 1) progress.cancel()
class ProgressCallbackWidget(ClientCallback): def __init__(self, parent): ClientCallback.__init__(self) self._parent = parent self._block = False self._label_text = '' self._title_text = '' self._updated_text = '' self._finished_text = '' self._cancellable = True self.status_progress = QProgressDialog(self._parent, Qt.Dialog) self.set_range(0, 1) def __del__(self): self.status_progress.close() del self.status_progress def set_block(self, block): self._block = block def set_title_text(self, title_text): self._title_text = title_text def set_label_text(self, label_text): self._label_text = label_text def set_updated_text(self, updated_text): self._updated_text = updated_text def set_finished_text(self, finished_label): self._finished_text = finished_label def set_cancellable(self, cancellable): if not self._cancellable and cancellable: log.warning( 'ProgressCallbackWidget.set_cancellable({cancellable}): invalid operation' .format(cancellable=cancellable)) if cancellable: if not self._cancellable: self.status_progress.setCancelButton(QPushButton(_('Cancel'))) else: self.status_progress.setCancelButton(None) self._cancellable = cancellable def on_show(self): # FIXME: status_progress may be None if on_update is called BEFORE show.. # FIXME: rename to start.. self.status_progress.reset() self.set_block(self._block) self.set_cancellable(self._cancellable) self.status_progress.setWindowTitle(self._title_text) self.status_progress.setLabelText(self._label_text) minimum, maximum = self.get_range() self.status_progress.setMinimum(minimum) self.status_progress.setMaximum(maximum) self.status_progress.show() if self._block: self._parent.setCursor(Qt.WaitCursor) def on_update(self, value, *args, **kwargs): self.status_progress.setValue(value) if self._updated_text: # FIXME: let the caller format the strings updatedMsg = self._updated_text.format(*args) self.status_progress.setLabelText(updatedMsg) QCoreApplication.processEvents() def on_finish(self, *args, **kwargs): # FIXME: let the caller format the strings finishedMsg = self._finished_text.format(*args) self.status_progress.setLabelText(finishedMsg) self.status_progress.done(0) if self._block: self._parent.setCursor( Qt.ArrowCursor ) # FIXME: restoreCursor? setCursor only in this class!! QCoreApplication.processEvents() def on_rangeChange(self, minimum, maximum): self.status_progress.setMinimum(minimum) self.status_progress.setMaximum(maximum) QCoreApplication.processEvents() def on_cancel(self): self.status_progress.cancel() if self._block: self._parent.setCursor(Qt.ArrowCursor) QCoreApplication.processEvents() def canceled(self): return self.status_progress.wasCanceled()
class ProcessCombine(QObject): """ Scans through the gpx files and initialize the GpxToFeature tool to import to create the features and finally combine the features as a single layer. """ progress = pyqtSignal(str) def __init__(self, parent): """ Initializes the processCombine :param parent: The parent of QObject :type parent: QWidget """ QObject.__init__(self, parent) self._parent = parent self.init_progress_dialog() self.layer_fields = None global ID_NUMBER ID_NUMBER = 0 global STOP_IMPORT STOP_IMPORT = False self.number_of_gpx_files = 0 def init_progress_dialog(self): """ Initializes the progress dialog. """ self.progress_dlg = QProgressDialog(self._parent) self.progress_dlg.resize(340, self.progress_dlg.height()) title = QApplication.translate('ProcessCombine', 'Importing...') self.progress_dlg.setWindowTitle(title) label = QLabel() label.setWordWrap(True) label.setMinimumHeight(17) self.progress_dlg.setMinimumWidth(500) self.progress_dlg.setMaximumWidth(500) self.progress_dlg.setLabel(label) self.progress_dlg.setValue(0) self.progress_dlg.canceled.connect(self.on_stop_importing) self.progress_dlg.open() @staticmethod def on_stop_importing(): """ A slot raised to stops the importing process. This happens when the progress dialog cancel button is clicked. """ global STOP_IMPORT STOP_IMPORT = True def on_update_progress(self, progress): """ A slot raised used to update the progress by emitting progress message from GpxToFeature signal called progress. :param progress: The progress message. :type progress: String """ self.progress.emit(progress) def gpx_to_feature_list(self, parm_store): """ Gets QgsFeature list by supplying gpx files. :param parm_store: The parameter store object :type parm_store: Class """ feature_list = [] for dir_path, sub_dirs, files in os.walk(parm_store.input_path): QApplication.processEvents() if STOP_IMPORT: return None # Exclude sub-folders if user have chosen not to scan sub-folders if not parm_store.scan_sub_folders: if dir_path != parm_store.input_path: continue gpx_files = glob.glob('{0}/{1}*{2}.gpx'.format( dir_path, parm_store.file_name_prefix, parm_store.file_name_suffix )) gpx_count = len(gpx_files) if gpx_count == 0: continue self.number_of_gpx_files += gpx_count self.progress_dlg.setRange(0, len(gpx_files)) for i, gpx_file in enumerate(gpx_files): QApplication.processEvents() if STOP_IMPORT: return None gpx_path = os.path.join(dir_path, gpx_file) parent_path = os.path.dirname(parm_store.input_path) relative_path = os.path.relpath(gpx_path, parent_path) scanning = QApplication.translate('ProcessCombine', 'Scanning') text = '{} {}'.format(scanning, relative_path) self.progress_dlg.setLabelText(text) gpx_to_layer = GpxToFeature(parm_store) gpx_to_layer.progress.connect(self.on_update_progress) gpx_to_layer.init_gpx_import(gpx_path) if not STOP_IMPORT: self.progress_dlg.setValue(i) # fet layer fields once if len(gpx_to_layer.final_features) > 0: if self.layer_fields is None: self.layer_fields = gpx_to_layer.layer_fields feature_list.extend(gpx_to_layer.final_features) return feature_list def combine_features(self, parm_store): """ Combines all features under one layer. :param parm_store: The parameter store object :type parm_store: Class :return: :rtype: """ final_layer = QgsVectorLayer( "{0}?crs=epsg:{1}&field=id:integer&index=yes".format( parm_store.geometry_type, parm_store.gpx_projection ), parm_store.layer_name, "memory" ) feature_list = self.gpx_to_feature_list(parm_store) if self.layer_fields is None: self.progress_dlg.blockSignals(True) self.progress_dlg.close() self.progress_dlg.blockSignals(False) return 0 if STOP_IMPORT: return provider = final_layer.dataProvider() final_layer.startEditing() provider.addAttributes(self.layer_fields) final_layer.updateFields() provider.addFeatures(feature_list) final_layer.commitChanges() final_layer.updateExtents() QgsProject.instance().addMapLayer(final_layer) return len(feature_list) def finish_import(self, parm_store): """ Finishes the import process. :param parm_store: The parameter store object :type parm_store: Class :return: None if the process is aborted or number_features is None :rtype: NoneType """ number_of_features = self.combine_features(parm_store) if STOP_IMPORT: abort_text = QApplication.translate( 'ProcessCombine', '<html><b>The importing process is aborted!</b></html>' ) self.progress.emit(abort_text) return if number_of_features is None: return if number_of_features < 1: end_text = QApplication.translate( 'ProcessCombine', '<html><b>Sorry, no valid GPX features found ' 'in the folder!</b</html>' ) self.progress.emit(end_text) self.progress_dlg.cancel() return self.copy_gpx_files(VALID_GPX_FILES, parm_store.valid_gpx_folder) self.copy_gpx_files(INVALID_GPX_FILES, parm_store.invalid_gpx_folder) self.progress_dlg.cancel() a = QApplication.translate('ProcessCombine', '<html><b>Successfully imported') c = QApplication.translate('ProcessCombine', 'features from') d = QApplication.translate('ProcessCombine', 'gpx files!<br>') e = QApplication.translate('ProcessCombine', 'You can view the result in') g = QApplication.translate('ProcessCombine', 'layer.</b</html>') end_text = '{} {} {} {} {} {} {} {}'.format( a, number_of_features, c, self.number_of_gpx_files, d, e, parm_store.layer_name, g ) self.progress.emit(end_text) @staticmethod def copy_gpx_files(source_files, destination_folder): """ Copies gpx files from a source folder to a destination folder. :param source_files: The source folder :type source_files: String :param destination_folder: The destination folder :type destination_folder: String """ for gpx_path in source_files: gpx_file = os.path.basename(gpx_path) destination = os.path.join(destination_folder, gpx_file) QApplication.processEvents() shutil.copyfile(gpx_path, destination)
class SearchPanel(QWidget): """ SearchPanel """ onShowMemoryRequest = pyqtSignal(str, name='onShowMemoryRequest') def __init__(self, parent=None, show_progress_dlg=False): super(SearchPanel, self).__init__(parent=parent) self._app_window = parent if self._app_window.dwarf is None: print('SearchPanel created before Dwarf exists') return self._app_window.dwarf.onMemoryScanResult.connect( self._on_search_result) self._ranges_model = None self._result_model = None self._blocking_search = show_progress_dlg self.progress = None self._pattern_length = 0 self._search_results = [] self.setContentsMargins(0, 0, 0, 0) main_wrap = QVBoxLayout() main_wrap.setContentsMargins(1, 1, 1, 1) wrapping_wdgt = QWidget() wrapping_wdgt.setContentsMargins(10, 10, 10, 10) v_box = QVBoxLayout(wrapping_wdgt) v_box.setContentsMargins(0, 0, 0, 0) self.input = QLineEdit() self.input.setPlaceholderText( 'search for a sequence of bytes in hex format: deadbeef123456aabbccddeeff...' ) v_box.addWidget(self.input) self.check_all_btn = QPushButton('check all') self.check_all_btn.clicked.connect(self._on_click_check_all) self.uncheck_all_btn = QPushButton('uncheck all') self.uncheck_all_btn.clicked.connect(self._on_click_uncheck_all) self.search_btn = QPushButton('search') self.search_btn.clicked.connect(self._on_click_search) h_box = QHBoxLayout() h_box.addWidget(self.check_all_btn) h_box.addWidget(self.uncheck_all_btn) h_box.addWidget(self.search_btn) v_box.addLayout(h_box) main_wrap.addWidget(wrapping_wdgt) self.ranges = DwarfListView(self) self.ranges.clicked.connect(self._on_show_results) self.results = DwarfListView(self) self.results.setVisible(False) h_box = QHBoxLayout() h_box.setContentsMargins(0, 0, 0, 0) h_box.addWidget(self.ranges) h_box.addWidget(self.results) main_wrap.addLayout(h_box) main_wrap.setSpacing(0) self.setLayout(main_wrap) self._setup_models() # ************************************************************************ # **************************** Functions ********************************* # ************************************************************************ def _setup_models(self): self._ranges_model = QStandardItemModel(0, 7) # just replicate ranges panel model self._ranges_model.setHeaderData( 0, Qt.Horizontal, 'x' ) # TODO: replace with checkbox in header - remove checkall btns self._ranges_model.setHeaderData(0, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(1, Qt.Horizontal, 'Address') self._ranges_model.setHeaderData(1, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(2, Qt.Horizontal, 'Size') self._ranges_model.setHeaderData(2, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(3, Qt.Horizontal, 'Protection') self._ranges_model.setHeaderData(3, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(4, Qt.Horizontal, 'FileOffset') self._ranges_model.setHeaderData(4, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(5, Qt.Horizontal, 'FileSize') self._ranges_model.setHeaderData(5, Qt.Horizontal, Qt.AlignCenter, Qt.TextAlignmentRole) self._ranges_model.setHeaderData(6, Qt.Horizontal, 'FilePath') self.ranges.setModel(self._ranges_model) self.ranges.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self.ranges.header().setSectionResizeMode(1, QHeaderView.ResizeToContents) self.ranges.header().setSectionResizeMode(2, QHeaderView.ResizeToContents) self.ranges.header().setSectionResizeMode(3, QHeaderView.ResizeToContents) self.ranges.header().setSectionResizeMode(4, QHeaderView.ResizeToContents) self.ranges.header().setSectionResizeMode(5, QHeaderView.ResizeToContents) self.ranges.doubleClicked.connect(self._on_range_dblclick) # setup results model self._result_model = QStandardItemModel(0, 1) self._result_model.setHeaderData(0, Qt.Horizontal, 'Address') self.results.setModel(self._result_model) self.results.doubleClicked.connect(self._on_dblclicked) def set_ranges(self, ranges): """ Fills Rangelist with Data """ self.ranges.header().setSectionResizeMode(0, QHeaderView.Fixed) if isinstance(ranges, list): self._ranges_model.removeRows(0, self._ranges_model.rowCount()) for range_entry in ranges: if 'protection' in range_entry and isinstance( range_entry['protection'], str): if 'r' not in range_entry['protection']: # skip not readable range continue else: continue # create items to add str_frmt = '' if self.ranges._uppercase_hex: str_frmt = '0x{0:X}' else: str_frmt = '0x{0:x}' addr = QStandardItem() addr.setTextAlignment(Qt.AlignCenter) addr.setText(str_frmt.format(int(range_entry['base'], 16))) size = QStandardItem() size.setTextAlignment(Qt.AlignRight) size.setText("{0:,d}".format(int(range_entry['size']))) protection = QStandardItem() protection.setTextAlignment(Qt.AlignCenter) protection.setText(range_entry['protection']) file_path = None file_addr = None file_size = None if len(range_entry) > 3: if range_entry['file']['path']: file_path = QStandardItem() file_path.setText(range_entry['file']['path']) if range_entry['file']['offset']: file_addr = QStandardItem() file_addr.setTextAlignment(Qt.AlignCenter) file_addr.setText( str_frmt.format(range_entry['file']['offset'])) if range_entry['file']['size']: file_size = QStandardItem() file_size.setTextAlignment(Qt.AlignRight) file_size.setText("{0:,d}".format( int(range_entry['file']['size']))) checkbox = QStandardItem() checkbox.setCheckable(True) self._ranges_model.appendRow([ checkbox, addr, size, protection, file_addr, file_size, file_path ]) # ************************************************************************ # **************************** Handlers ********************************** # ************************************************************************ def _on_range_dblclick(self, model_index): item = self._ranges_model.itemFromIndex(model_index) if item: if self._ranges_model.item(model_index.row(), 0).checkState() != Qt.Checked: self._ranges_model.item(model_index.row(), 0).setCheckState(Qt.Checked) else: self._ranges_model.item(model_index.row(), 0).setCheckState(Qt.Unchecked) def _on_click_check_all(self): for i in range(self._ranges_model.rowCount()): self._ranges_model.item(i, 0).setCheckState(Qt.Checked) def _on_click_uncheck_all(self): for i in range(self._ranges_model.rowCount()): self._ranges_model.item(i, 0).setCheckState(Qt.Unchecked) def _on_dblclicked(self, model_index): item = self._result_model.itemFromIndex(model_index) if item: self.onShowMemoryRequest.emit( self._result_model.item(model_index.row(), 0).text()) def _on_click_search(self): pattern = self.input.text() if pattern == '': return 1 # check if we already provide a hex string as input try: test = pattern.replace(' ', '') int(test, 16) pattern = test except ValueError: # search for string pattern = binascii.hexlify(pattern.encode('utf8')).decode('utf8') ranges = [] self._search_results = [] for i in range(self._ranges_model.rowCount()): item = self._ranges_model.item(i, 0) if item.checkState() == Qt.Checked: addr = self._ranges_model.item(i, 1) size = self._ranges_model.item(i, 2) ranges.append([addr.text(), size.text()]) if len(ranges) == 0: return 1 if self._blocking_search: self.progress = QProgressDialog() self.progress.setFixedSize(300, 50) self.progress.setAutoFillBackground(True) self.progress.setWindowModality(Qt.WindowModal) self.progress.setWindowTitle('Please wait') self.progress.setLabelText('searching...') self.progress.setSizeGripEnabled(False) self.progress.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.progress.setWindowFlag(Qt.WindowContextHelpButtonHint, False) self.progress.setWindowFlag(Qt.WindowCloseButtonHint, False) self.progress.setModal(True) self.progress.setCancelButton(None) self.progress.setRange(0, 0) self.progress.setMinimumDuration(0) self.progress.forceShow() self._app_window.show_progress('searching...') self.input.setEnabled(False) self.search_btn.setEnabled(False) self.check_all_btn.setEnabled(False) self.uncheck_all_btn.setEnabled(False) self._pattern_length = len(pattern) * .5 search_thread = SearchThread(self._app_window.dwarf, self) search_thread.onCmdCompleted.connect(self._on_search_complete) search_thread.onError.connect(self._on_search_error) search_thread.pattern = pattern search_thread.ranges = ranges search_thread.start() def _on_search_result(self, data): self._search_results.append(data) def _on_search_complete(self): self.input.setEnabled(True) self.search_btn.setEnabled(True) self.check_all_btn.setEnabled(True) self.uncheck_all_btn.setEnabled(True) self._app_window.hide_progress() if self._blocking_search: self.progress.cancel() self._ranges_model.removeColumns(4, 3) self._ranges_model.setHeaderData(3, Qt.Horizontal, 'Search Results') self._ranges_model.setHeaderData(3, Qt.Horizontal, None, Qt.TextAlignmentRole) results_count = 0 is_selected = False for i in range(self._ranges_model.rowCount()): item = self._ranges_model.item(i, 0) if item.checkState() == Qt.Checked: item.setCheckState(Qt.Unchecked) if not is_selected: is_selected = True self.ranges.setCurrentIndex(self._ranges_model.index(i, 0)) else: self._search_results.insert(i, None) self._ranges_model.item(i, 3).setText('') self._ranges_model.item(i, 3).setTextAlignment(Qt.AlignLeft) continue if len(self._search_results[i]): results_count += len(self._search_results[i]) self._ranges_model.item(i, 3).setText('Matches: {0}'.format( len(self._search_results[i]))) self._ranges_model.item(i, 3).setTextAlignment(Qt.AlignLeft) else: self._ranges_model.item(i, 3).setText('') self._ranges_model.item(i, 3).setTextAlignment(Qt.AlignLeft) self._app_window.set_status_text( 'Search complete: {0} matches'.format(results_count)) if results_count: for i in self._search_results: if i and len(i): self.results.setVisible(True) for result in i: self._result_model.appendRow( QStandardItem(result['address'])) break def _on_search_error(self, msg): utils.show_message_box(msg) def _on_show_results(self): if self._search_results: self.results.clear() if self._app_window.memory_panel: self._app_window.memory_panel.remove_highlights('search') selected_index = self.ranges.selectionModel().currentIndex().row() if selected_index is not None: item_txt = self._ranges_model.item(selected_index, 3).text() if item_txt == '': return for result in self._search_results[selected_index]: self._result_model.appendRow( QStandardItem(result['address'])) # TODO: fix hexview highlights performance """
class DownloadProgress(QObject): """ Dialog which is shown during download and parsing of the data. Displays the progress of the task of downloading and parsing. Creates a worker thread to do the actual download process in the background. """ finishedSignal = pyqtSignal(OrderedDict, dict, name="processFinished") def __init__(self, parent): super(DownloadProgress, self).__init__(parent) self.parent = parent self.progressDialog = None self.worker = None self.thread = None def begin_download(self, request_params, request_function): self.progressDialog = QProgressDialog(self.parent, Qt.WindowSystemMenuHint | Qt.WindowTitleHint) self.progressDialog.setWindowTitle(Messages.downloading_weatherdata()) self.progressDialog.setAutoClose(False) self.progressDialog.setCancelButton(None) self.progressDialog.setLabelText(Messages.downloading_weatherdata()) self.progressDialog.open() self.progressDialog.setValue(0) self.request_params = request_params self.worker = DownloadWorker(request_params, request_function) self.worker.threadUpdateSignal.connect(self._update_progress_bar) self.worker.threadExceptionSignal.connect(self._loading_failed) self.worker.threadResultsSignal.connect(self._process_finished) self.worker.threadChangeTaskSignal.connect(self._change_progress_dialog) self.thread = QThread() self.worker.moveToThread(self.thread) self.thread.started.connect(self.worker.download_data) self.thread.start() @pyqtSlot(int, int, name="progressUpdate") def _update_progress_bar(self, i, max_value): self.progressDialog.setRange(0, max_value) self.progressDialog.setValue(i) @pyqtSlot(object, name="exceptionInProcess") def _loading_failed(self, error): self.progressDialog.cancel() try: raise error except RequestException as e: if e.error_code == 400: # command to ask data probably invalid or there is a problem with current station self.parent.show_error_alerts(Messages.weatherstation_error() + str(e)) else: self.parent.show_error_alerts(Messages.unknown_error() + str(e)) except InvalidApikeyException: # apikey is invalid self.parent.show_error_alerts(Messages.request_failed_error()) except NoDataException: self.parent.show_error_alerts(Messages.date_not_found_error()) except QueryLimitException as e: self.parent.show_error_alerts(Messages.query_limit_error().format(e.wait_time)) except Exception as e: self.parent.show_error_alerts(Messages.unknown_error() + str(e)) @pyqtSlot(str, name="progressChange") def _change_progress_dialog(self, header): """ When the "topic" of the progress bar changes from download to parsing for example. :param header: :return: """ self.progressDialog.setLabelText(header) self.progressDialog.setValue(0) @pyqtSlot(list, name="results") def _process_finished(self, result): self.result = result self.progressDialog.close() self.finishedSignal.emit(self.result, self.request_params)
class MWindow(QMainWindow): def __init__(self): super(MWindow, self).__init__() #gecko driver çalışması için yolda olması gerekiyor. if not os.getcwd() in sys.path: sys.path.append(os.getcwd()) uic.loadUi("ui/anasayfa.ui", self) self.setFixedSize(700, 620) self.labelHata.setText("") self.btnFormuTemizle.clicked.connect(self.formuTemizle) self.btnSorgula.clicked.connect(self.hesSorgula) self.btnKayitEkle.clicked.connect(lambda: self.ekleGuncelle("ekle")) self.btnGuncelle.clicked.connect(self.btnGuncelleClicked) self.btnSil.clicked.connect(self.sil) self.btnHepsiniSil.clicked.connect(self.veritabaniniTemizle) self.btnYardim.clicked.connect(self.yardim) self.sinifIslemleri() self.btnSinifSorgula.clicked.connect(self.btnSinifSorgulaClicked) self.dosyaSecButton.clicked.connect(self.dosyaSec) self.dizinSecButton.clicked.connect(self.dizinSec) self.topluKaydetButton.clicked.connect(self.topluKaydet) self.btnSinifSil.clicked.connect(self.sinifSilClicked) self.resim.setPixmap(QPixmap(PHOTO_PLACEHOLDER)) self.show() #Bu gizli butonlar thread içinden arayüzde yapılacak değişiklikler için eklendi. #Doğru yol olmayabilir ama işe yarıyor :) self.animasyonKapatButon = QPushButton(self) self.animasyonKapatButon.clicked.connect( self.yukleniyorAnimasyonuKapat) self.animasyonKapatButon.hide() self.tabloGonderButton = QPushButton(self) self.tabloGonderButton.clicked.connect(self.tabloIsle) self.tabloGonderButton.hide() self.hataMesajiButton = QPushButton(self) self.hataMesajiButton.clicked.connect(self.hataMesaji) self.hataMesajiButton.hide() self.btnSinifIslemleri = QPushButton(self) self.btnSinifIslemleri.clicked.connect(self.sinifIslemleri) self.btnSinifIslemleri.hide() self.mesaj = "" self.timer = QTimer(self) def hataMesaji(self): self.timer.stop() mesaj = self.mesaj self.labelHata.setText(mesaj) self.timer.timeout.connect(self.hataMesajiKapat) self.timer.start(5000) def hataMesajiKapat(self): self.labelHata.setText("") self.timer.stop() def veritabaniniTemizle(self): qm = QMessageBox(self) mesaj = "Tüm bilgiler silinecek. Onaylıyor musunuz?" ret = qm.warning(self, 'Hepsini Sil', mesaj, qm.Yes | qm.No) if ret == qm.Yes: vt.DB.veritabanisil() self.formuTemizle() self.sinifIslemleri() self.mesaj = "Tüm veriler silindi." self.hataMesaji() def yukleniyorAnimasyonuBaslat(self, parent=None): self.dialogMessage = "İşlem devam ediyor..." if parent == None: self.pb = QProgressDialog(self) else: self.pb = QProgressDialog(parent) pb = self.pb pb.setLabelText(self.dialogMessage) pb.setStyleSheet("color:blue;background-color:orange;") pb.setWindowFlag(Qt.FramelessWindowHint) pb.setCancelButton(None) pb.setRange(0, 0) pb.setMinimumDuration(0) pb.show() def yukleniyorAnimasyonuKapat(self): self.pb.cancel() def ogrenciGoster(self, ogrenci): if len(ogrenci) == 0: return self.tcNo.setText(ogrenci[TC_NO_INDEX]) self.ad.setText(ogrenci[AD_INDEX]) self.soyad.setText(ogrenci[SOYAD_INDEX]) self.okulNo.setText(str(ogrenci[OKUL_NO_INDEX])) self.sinif.setText(ogrenci[SINIF_INDEX]) self.resim.setPixmap(ogrenci[RESIM_INDEX]) self.hesKodu.setText(ogrenci[HES_KODU_INDEX]) #self.durum.setText(str(ogrenci[DURUM_INDEX])) def hesSorgula(self): self.labelHata.setText("") ogrenci = [] #*Tc noya göre veritabanı sorgulamasında birden fazla sonuç gelebilir. self.tekHesSorguSonucu = [] hes_kodu = "" hesKoduKayitli = True if self.okulNo.text() != "": no = self.okulNo.text() self.formuTemizle() if not no.isnumeric(): self.mesaj = "Geçerli okul numarası girmelisiniz!" self.hataMesajiButton.click() return ogrenci = vt.DB.okul_no_ile(int(no)) if len(ogrenci) == 0: self.mesaj = "Bu numara kayıtlı değil." self.hataMesajiButton.click() return self.ogrenciGoster(ogrenci) hes_kodu = ogrenci[HES_KODU_INDEX] elif self.tcNo.text() != "": ogrenci = vt.DB.tc_no_ile(self.tcNo.text()) self.formuTemizle() if len(ogrenci) == 0: self.mesaj = "Bu TC no kayıtlı değil." self.hataMesajiButton.click() return self.ogrenciGoster(ogrenci) hes_kodu = ogrenci[HES_KODU_INDEX] elif self.hesKodu.text() != "": ogrenci = vt.DB.hes_kodu_ile(self.hesKodu.text()) if len(ogrenci) == 0: hes_kodu = self.hesKodu.text() hesKoduKayitli = False else: self.formuTemizle() self.ogrenciGoster(ogrenci) hes_kodu = ogrenci[HES_KODU_INDEX] else: self.mesaj = "Okul no, TC no veya HES kodu girmelisiniz!" self.hataMesajiButton.click() return if self.kullaniciAdi.text() != "" and self.sifre.text() != "": #Girilen bilgiye göre öğrenci kayıtlıysa gösterildi. Hes kodu sorgulanacak. self.yukleniyorAnimasyonuBaslat() #Firefox yeni bir threadde açılmalı yoksa arayüzü kilitliyor. self.mThread = Thread(target=self.eDevlettenSorgula, args=(hes_kodu, hesKoduKayitli)) self.mThread.start() else: #*Kullanıcı adı veya şifresi boş self.mesaj = "e-Devlet kullanıcı adı ve şifresini girmelisiniz." self.hataMesajiButton.click() return def formuTemizle(self): self.okulNo.setText("") self.ad.setText("") self.soyad.setText("") self.sinif.setText("") self.tcNo.setText("") self.hesKodu.setText("") self.durum.setText("") self.resim.setPixmap(QPixmap(PHOTO_PLACEHOLDER)) def yardim(self): yardim = QDialog(self) uic.loadUi("ui/yardim.ui", yardim) yardim.setFixedSize(610, 450) yardim.exec_() def btnGuncelleClicked(self): if self.kullaniciAdi.text() == "" or self.sifre.text() == "": self.mesaj = "E-Devlet bilgilerini girmeden güncelleme yapılamaz!" self.hataMesajiButton.click() return tmp_no = self.okulNo.text() ogrenci = [] if tmp_no != "" and tmp_no.isnumeric(): ogrenci = vt.DB.okul_no_ile(tmp_no) if len(ogrenci) == 0: self.mesaj = "Bu numaraya sahip öğrenci yok!" self.hataMesajiButton.click() else: self.ogrenciGoster(ogrenci) self.ekleGuncelle("güncelle") def ekleGuncelle(self, eylem): if eylem == "ekle": if self.kullaniciAdi.text() == "" or self.sifre.text() == "": self.mesaj = "E-Devlet bilgilerini girmeden kayıt ekleme yapılamaz!" self.hataMesajiButton.click() return self.eklenenResim = "" self.ekleGuncellePencere = QDialog(self) uic.loadUi("ui/ekleGuncelle.ui", self.ekleGuncellePencere) self.ekleGuncellePencere.setFixedSize(450, 280) self.ekleGuncellePencere.hata.hide() if eylem == "ekle": self.ekleGuncellePencere.setWindowTitle("Ekle") self.ekleGuncellePencere.widgetKaydet.setText("Kaydet") elif eylem == "güncelle": self.ekleGuncellePencere.setWindowTitle("Güncelle") self.ekleGuncellePencere.widgetKaydet.setText("Güncelle") self.ekleGuncellePencere.widgetOkulNo.setText(self.okulNo.text()) self.ekleGuncellePencere.widgetOkulNo.setEnabled(False) self.ekleGuncellePencere.widgetAdi.setText(self.ad.text()) self.ekleGuncellePencere.widgetAdi.setEnabled(False) self.ekleGuncellePencere.widgetSoyadi.setText(self.soyad.text()) self.ekleGuncellePencere.widgetSoyadi.setEnabled(False) self.ekleGuncellePencere.widgetSinifi.setText(self.sinif.text()) self.ekleGuncellePencere.widgetTcKimlikNo.setText(self.tcNo.text()) self.ekleGuncellePencere.widgetTcKimlikNo.setEnabled(False) self.ekleGuncellePencere.widgetHesKodu.setText(self.hesKodu.text()) res = self.resim.pixmap() if res: self.ekleGuncellePencere.widgetResim.setPixmap(res) self.ekleGuncellePencere.widgetIptal.clicked.connect( self.ekleGuncellePencere.destroy) self.ekleGuncellePencere.widgetKaydet.clicked.connect(self.kaydet) self.ekleGuncellePencere.widgetResimEkle.clicked.connect( self.resimEkle) self.ekleGuncellePencere.exec_() def resimEkle(self): resimAdi, _ = QFileDialog.getOpenFileName(self.ekleGuncellePencere, "Resim seç...", "C:\\") try: if resimAdi != "": mResim = QPixmap(resimAdi) self.ekleGuncellePencere.widgetResim.setPixmap(mResim) self.eklenenResim = resimAdi except: return def kaydet(self): self.ekleGuncellePencere.hata.hide() kimlikNo = self.ekleGuncellePencere.widgetTcKimlikNo.text() hesKodu = self.ekleGuncellePencere.widgetHesKodu.text() ad = self.ekleGuncellePencere.widgetAdi.text() soyad = self.ekleGuncellePencere.widgetSoyadi.text() sinif = self.ekleGuncellePencere.widgetSinifi.text() okulNo = self.ekleGuncellePencere.widgetOkulNo.text() ogrenci = [ kimlikNo, ad, soyad, okulNo, sinif, self.eklenenResim, hesKodu, "1" ] if self.ekleGuncellePencere.widgetKaydet.text() == "Kaydet": #*Bilgilerde eksiklik varsa durdurulacak. bilgilerTam = hesKodu != "" and kimlikNo != "" and ad != "" and self.eklenenResim != "" and soyad != "" and sinif != "" and okulNo != "" if not bilgilerTam: self.ekleGuncellePencere.hata.show() self.ekleGuncellePencere.hata.setText("Bilgiler eksik!") return #Öğrenci zaten kayıtlı mı kontrol ediliyor. numaraKayitli = vt.DB.okul_no_ile(ogrenci[OKUL_NO_INDEX]) tcNoKayitli = vt.DB.tc_no_ile(ogrenci[TC_NO_INDEX]) hesKayitli = vt.DB.hes_kodu_ile(ogrenci[HES_KODU_INDEX]) if len(numaraKayitli) > 0 or len(tcNoKayitli) > 0 or len( hesKayitli) > 0: self.ekleGuncellePencere.hata.show() self.ekleGuncellePencere.hata.setText( "Öğrenci zaten kayıtlı. Düzenlemek için Güncelle bölümünü kullanın." ) return try: self.yukleniyorAnimasyonuBaslat() th = Thread(target=self.eDevlettenGrupGuncelleSayfasiAc, args=(E_DEVLET_GRUP_ADI, True, ogrenci)) th.start() except: self.animasyonKapatButon.click() self.ekleGuncellePencere.hata.show() self.ekleGuncellePencere.hata.setText( "Öğrenci zaten kayıtlı. Düzenlemek için Güncelle bölümünü kullanın." ) #Güncelleme sayfasındayız. else: bilgilerTam = hesKodu != "" and sinif != "" if not bilgilerTam: self.ekleGuncellePencere.hata.show() self.ekleGuncellePencere.hata.setText("Bilgiler eksik!") return #Hes kodu değişmedi, sadece veritabanına yazılacak. if self.hesKodu.text() == hesKodu: if self.eklenenResim != "": vt.DB.toplu_kayit_ekle([ogrenci]) else: vt.DB.veriguncelle(okulNo, sinif, hesKodu) self.sinif.setText(sinif) #Hes değişti. E-devletten hes kodu eklenecek. Eklenirse veritabanına kaydedilecek. else: if self.eklenenResim != "": self.yukleniyorAnimasyonuBaslat() th = Thread(target=self.eDevlettenGrupGuncelleSayfasiAc, args=(E_DEVLET_GRUP_ADI, True, ogrenci)) th.start() #Yeni resim eklenmediyse eski öğrenci güncellenecek. else: self.yukleniyorAnimasyonuBaslat() th = Thread(target=self.eDevlettenGrupGuncelleSayfasiAc, args=(E_DEVLET_GRUP_ADI, True, ogrenci, True)) th.start() self.ekleGuncellePencere.close() def grubaHesEkle(self, hes, browserAc=True): if browserAc: if not self.eDevletGirisiYap(): self.mesaj = "E-Devlet girişi yapılamadı!" self.hataMesajiButton.click() return br = self.br self.elemanYuklenmesiniBekle(id="hesKodu") br.find_element_by_id("hesKodu").clear() br.find_element_by_id("hesKodu").send_keys(hes) br.find_element_by_name("btn").click() self.elemanYuklenmesiniBekle(sinif="actionButton") if len(br.find_elements_by_class_name("confirmContainer")) > 0: return True else: return False #Öğrenci sil def sil(self): okulNo = self.okulNo.text() if okulNo != "" and okulNo.isnumeric(): ogrenci = vt.DB.okul_no_ile(int(okulNo)) if len(ogrenci) > 0: self.ogrenciGoster(ogrenci) qm = QMessageBox(self) ret = qm.question(self, 'Sil', "Öğrenci silisin mi?", qm.Yes | qm.No) if ret == qm.Yes: vt.DB.kayitsil(int(okulNo)) self.mesaj = "Öğrenci silindi." self.hataMesajiButton.click() self.formuTemizle() else: self.mesaj = "Kayıt yok!" self.hataMesajiButton.click() else: self.mesaj = "Sileceğiniz öğrencinin numarasını girmediniz!" self.hataMesajiButton.click() def sonucGeldimi(self): try: br = self.br tc_sonu = br.find_elements_by_class_name( "compact")[0].find_elements_by_tag_name("dd")[1].get_attribute( "innerText") ad_soyad = br.find_elements_by_class_name( "compact")[0].find_elements_by_tag_name("dd")[0].get_attribute( "innerText") durum = br.find_elements_by_class_name( "compact")[0].find_elements_by_tag_name("dd")[3].get_attribute( "innerText") return (tc_sonu, ad_soyad, durum) except: return (False, False, False) def eDevletGirisiYap(self, tcKimlik="", sifre="", gizliPencere=TARAYICIYI_GIZLE): try: if tcKimlik == "" and sifre == "": tcKimlik = self.kullaniciAdi.text() sifre = self.sifre.text() if tcKimlik == "" or sifre == "": return False url = "https://giris.turkiye.gov.tr/Giris/" #*E-devlete grup ekleneceği zaman gizliPencere=False olmalı, excel doyası yüklenmiyor yoksa. if gizliPencere: options = Options() options.add_argument('--headless') self.br = Firefox(executable_path="geckodriver", options=options) else: self.br = Firefox(executable_path="geckodriver") br = self.br br.get(url) br.find_element_by_id("tridField").send_keys(tcKimlik) br.find_element_by_id("egpField").send_keys(sifre) br.find_elements_by_class_name("submitButton")[0].click() self.elemanYuklenmesiniBekle(sinif="userMenuButton") if len(br.find_elements_by_class_name("userMenuButton")) > 0: return True else: return False except: return False def eDevletCikisYap(self): self.br.find_elements_by_class_name("userMenuButton")[0].click() self.br.find_elements_by_class_name("logout")[0].click() self.br.close() def eDevlettenSorgula(self, hesKodu, hesKoduKayitli=True): if self.eDevletGirisiYap(): self.pb.setLabelText("E-Devlet girişi yapıldı...") else: self.yukleniyorAnimasyonuKapat() self.mesaj = "E-Devlet girişi başarısız!" self.hataMesajiButton.click() return br = self.br url1 = "https://www.turkiye.gov.tr/saglik-bakanligi-hes-kodu-sorgulama" sayac = 0 br.get(url1) try: br.find_element_by_id("hes_kodu").send_keys(hesKodu) br.find_elements_by_class_name("submitButton")[0].click() self.pb.setLabelText("Sorgulanıyor...") while (True): tc_sonu, ad_soyad, durum = self.sonucGeldimi() #Hes kodu geçersiz uyarısı kontrol ediliyor. if len(br.find_elements_by_class_name("warningContainer")) > 0: tc_sonu, ad_soyad, durum = (False, False, False) break if tc_sonu or sayac > TIMEOUT: break sayac += 1 time.sleep(1) #* Burada edevletten sonuç gelmiş ve tc_sonu, hes ve durum değişkenlerine aktarılmış oluyor. #*Sonuç gelmemişse bu değişkenlere False değeri veriliyor. self.eDevletCikisYap() self.yukleniyorAnimasyonuKapat() if tc_sonu: if not hesKoduKayitli: son_uc = tc_sonu[-3:] ad = " ".join(ad_soyad.split(" ")[:-1]) soyad = ad_soyad.split(" ")[-1] ogrenciListe = vt.DB.tc_sonu_ile(son_uc, ad[:2], soyad[:2]) #Öğrenci veritabanında yoksa. if len(ogrenciListe) == 0: self.durum.setText(durum) self.tcNo.setText(tc_sonu) soyad = ad_soyad.split(" ")[-1] self.soyad.setText(soyad) ad = " ".join(ad_soyad.split(" ")[:-1]) self.ad.setText(ad) elif len(ogrenciListe) == 1: self.ogrenciGoster(ogrenciListe[0]) self.mesaj = "Olası eşleşme" self.hataMesajiButton.click() else: # Bir okul için çok düşük bir ihtimal bu. Sadece uyarıyla geçeceğim. self.ogrenciGoster(ogrenciListe[0]) self.tekHesSorguSonucu = ogrenciListe self.mesaj = "Olası eşleşmeler" self.hataMesajiButton.click() else: #Hes kodu kayıtlı, öğrenci zaten gösterildi. Durum yazılacak. self.durum.setText(durum) else: self.mesaj = "Hatalı hes kodu!" self.hataMesajiButton.click() except: br.close() self.yukleniyorAnimasyonuKapat() self.mesaj = "Beklenmeyen bir hata oluştu!" self.hataMesajiButton.click() #True döndürürse grup kaydedilmiş ve hes kodlarını kaydedilmiştir. def grupOlustur(self, grupAdi, tamDosyaYolu, ogrenciler, aciklama="", varolanGrubaEkle=False): try: if not varolanGrubaEkle: if not self.eDevletGirisiYap(): self.mesaj = "E-Devlet girişi yapılamadı." self.hataMesajiButton.click() return False self.pb.setLabelText("E-Devlet girişi yapıldı...") br = self.br url = "https://www.turkiye.gov.tr/saglik-bakanligi-toplu-hes-kodu-sorgulama?yeni=grup" br.get(url) br.find_element_by_id("grupAdi").clear() br.find_element_by_id("grupAdi").send_keys(grupAdi) br.find_element_by_id("grupAciklama").send_keys(aciklama) br.find_elements_by_class_name("submitButton")[0].click() if not self.elemanYuklenmesiniBekle(id="hesKodu"): return False self.pb.setLabelText("Grup oluşturuldu...") else: self.eDevlettenGrupGuncelleSayfasiAc(E_DEVLET_GRUP_ADI, browser=True) self.elemanYuklenmesiniBekle( linkText="Hes Kodlarını Excelden Yükle") br = self.br br.find_element_by_link_text( "Hes Kodlarını Excelden Yükle").click() self.elemanYuklenmesiniBekle(sinif="filedropzone") br.find_elements_by_class_name("filedropzone")[0].click() subprocess.call(["cscript.exe", "deneme.vbs", tamDosyaYolu]) time.sleep(4) br.find_element_by_name("btn").click() if self.elemanYuklenmesiniBekle(sinif="list-right"): if len(br.find_elements_by_class_name("confirmContainer")) > 0: self.pb.setLabelText("Hes listesi kaydedildi...") vt.DB.toplu_kayit_ekle(ogrenciler) br.close() self.btnSinifIslemleri.click() self.animasyonKapatButon.click() self.mesaj = "Liste kaydedildi." self.hataMesajiButton.click() return True else: self.animasyonKapatButon.click() self.mesaj = "Hata: Liste e-devlete kaydedilemedi!" self.hataMesajiButton.click() return False else: self.mesaj = "Hata: Liste e-devlete kaydedilemedi!" self.hataMesajiButton.click() self.animasyonKapatButon.click() return False except: self.mesaj = "Hata: Liste e-devlete kaydedilemedi!" self.hataMesajiButton.click() self.animasyonKapatButon.click() return False def eDevlettenGrupGuncelleSayfasiAc(self, grupAdi, browser=True, ogrenci=[], ogrenciGuncellenecek=False): try: if browser: if not self.eDevletGirisiYap(): return self.pb.setLabelText("E-Devlet girişi yapıldı...") br = self.br url = "https://www.turkiye.gov.tr/saglik-bakanligi-toplu-hes-kodu-sorgulama" br.get(url) self.elemanYuklenmesiniBekle(id="resultTable") listeler = br.find_elements_by_link_text("Güncelle") if len(listeler) == 0: return elif len(listeler) == 1: br.find_element_by_link_text("Güncelle").click() else: tumSutunlar = br.find_elements_by_tag_name("td") gruplar = [ i.text for i in tumSutunlar if tumSutunlar.index(i) % 4 == 0 ] grupIndex = gruplar.index(grupAdi) br.find_elements_by_link_text("Güncelle")[grupIndex].click() self.pb.setLabelText("Güncelleme sayfası açıldı...") #*İlgili grup güncellenmeye hazır. self.elemanYuklenmesiniBekle(sinif="actionButton") br.find_elements_by_class_name("actionButton")[1].click() self.elemanYuklenmesiniBekle(sinif="actionButton") if len(ogrenci) > 0: if self.grubaHesEkle(ogrenci[HES_KODU_INDEX], browserAc=False): self.pb.setLabelText("Hes kaydedildi...") if ogrenciGuncellenecek: vt.DB.veriguncelle(ogrenci[OKUL_NO_INDEX], ogrenci[SINIF_INDEX], ogrenci[HES_KODU_INDEX]) else: vt.DB.toplu_kayit_ekle([ogrenci]) self.sinif.setText(ogrenci[SINIF_INDEX]) self.hesKodu.setText(ogrenci[HES_KODU_INDEX]) self.mesaj = "Öğrenci kaydedildi." self.hataMesajiButton.click() self.animasyonKapatButon.click() br.close() else: self.mesaj = "Girilen HES kodu geçersiz!" self.hataMesajiButton.click() self.animasyonKapatButon.click() br.close() except: self.mesaj = "Beklenmeyen bir hata oluştu!" self.hataMesajiButton.click() self.animasyonKapatButon.click() self.br.close() def eDevletHesSil(self, hes, browserAc=True): try: if browserAc: self.eDevlettenGrupGuncelleSayfasiAc(E_DEVLET_GRUP_ADI) br = self.br #*İlk satır tablo başlıkları satirlar = br.find_elements_by_tag_name("tr") if len(satirlar) > 1: satir = satirlar[1] #*Satırların class hidden durumları değiştiriliyor.Yoksa 1. sayfadan sonrakiler görünmüyor. br.execute_script("arguments[0].setAttribute('class', '')", satir) sutunListesi = br.find_elements_by_tag_name("td") tumHesler = [ i.text for i in sutunListesi if sutunListesi.index(i) % 2 == 0 ] br.find_elements_by_link_text("Sil")[tumHesler.index( hes)].click() self.elemanYuklenmesiniBekle(sinif="actionButton") if len(br.find_elements_by_class_name("confirmContainer")) > 0: return True else: return False except: return False def edevlettenHepsiniSil(self): try: if not self.eDevletGirisiYap(): return br = self.br url = "https://www.turkiye.gov.tr/saglik-bakanligi-toplu-hes-kodu-sorgulama" br.get(url) self.elemanYuklenmesiniBekle(id="resultTable") while (len(br.find_elements_by_link_text("Sil")) > 0): br.find_element_by_link_text("Sil").click() self.elemanYuklenmesiniBekle(sinif="radioButton") br.find_element_by_class_name("radioButton").click() br.find_element_by_class_name("actionButton").click() self.elemanYuklenmesiniBekle(sinif="contentToolbar") br.find_element_by_partial_link_text("Grup Listesi").click() self.elemanYuklenmesiniBekle(id="resultTable") except: self.br.close() self.mesaj = "Gruplar e-devletten silinemedi!" self.hataMesajiButton.click() self.animasyonKapatButon.click() def elemanYuklenmesiniBekle(self, id="", sinif="", linkText=""): br = self.br timeout = TIMEOUT if id != "": while len(br.find_elements_by_id(id)) == 0 and timeout > 0: time.sleep(1) timeout -= 1 if timeout == 0: return False else: return True elif sinif != "": while len(br.find_elements_by_class_name( sinif)) == 0 and timeout > 0: time.sleep(1) timeout -= 1 if timeout == 0: return False else: return True elif linkText != "": while len(br.find_elements_by_link_text( linkText)) == 0 and timeout > 0: time.sleep(1) timeout -= 1 if timeout == 0: return False else: return True def sinifIslemleri(self): self.comboboxSinifSec.clear() siniflar = [] tmp_siniflar = vt.DB.sinif_isimleri() #[(sınıf,),(sınıf,),(sınıf,)] şeklinde geliyor veritabanından. for i in tmp_siniflar: siniflar.append(*i) #*Veritabanından çekilen sınıflar comboboxa aktarılıyor. self.comboboxSinifSec.addItems(siniflar) tablo = self.sorguSonucuTableWidget #*Resim, ad soyad, tc ve açıklama olacak şekilde 4 sütun. tablo.setColumnCount(4) tablo.setRowCount(1) item1 = QTableWidgetItem("Resim") item1.setTextAlignment(Qt.AlignCenter) item1.setBackground(QColor("#616161")) item1.setForeground(QColor("#ffffff")) tablo.setItem(0, 0, item1) item2 = QTableWidgetItem("Öğrenci") item2.setTextAlignment(Qt.AlignCenter) item2.setBackground(QColor("#616161")) item2.setForeground(QColor("#ffffff")) tablo.setItem(0, 1, item2) item3 = QTableWidgetItem("Okul No") item3.setTextAlignment(Qt.AlignCenter) item3.setBackground(QColor("#616161")) item3.setForeground(QColor("#ffffff")) tablo.setItem(0, 2, item3) item4 = QTableWidgetItem("Açıklama") item4.setTextAlignment(Qt.AlignCenter) item4.setBackground(QColor("#616161")) item4.setForeground(QColor("#ffffff")) tablo.setItem(0, 3, item4) tablo.verticalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) tablo.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) tablo.horizontalHeader().hide() tablo.verticalHeader().hide() def btnSinifSorgulaClicked(self): self.formuTemizle() if self.comboboxSinifSec.currentText() == "": self.mesaj = "Sorgulanacak sınıf yok!" self.hataMesaji() return if self.kullaniciAdi.text() != "" and self.sifre.text() != "": self.sorguSonucuLabel.setText("") self.yukleniyorAnimasyonuBaslat() th = Thread(target=self.sinifSorgula) th.start() else: self.mesaj = "E-Devlet kullanıcı adı ve şifrenizi girmelisiniz!" self.hataMesaji() def sinifSorgula(self): self.tabloyaGonderilenOgrenciler = [] self.tabloyaGonderilenSorunlar = [] sinif = self.comboboxSinifSec.currentText() if not self.eDevletGirisiYap(): self.yukleniyorAnimasyonuKapat() self.br.close() self.mesaj = "E-Devlet girişi yapılamadı!" self.hataMesajiButton.click() return br = self.br br.get( "https://www.turkiye.gov.tr/saglik-bakanligi-toplu-hes-kodu-sorgulama" ) self.elemanYuklenmesiniBekle(linkText="Yeni Grup Oluştur") url = "https://www.turkiye.gov.tr/saglik-bakanligi-toplu-hes-kodu-sorgulama?i=s&s=0" br.get(url) self.elemanYuklenmesiniBekle(sinif="compact") gecersizler = br.find_elements_by_css_selector( "table[summary='Geçersiz HES Kodu Listesi (Süresi dolmuş, Silinmiş)']" ) pozitifler = br.find_elements_by_css_selector( "table[summary='Riskli HES Kodu Listesi (Pozitif, Temaslı)']") if len(gecersizler) != 0 or len(pozitifler) != 0: #Tüm satırlar görünür hale getiriliyor. for eleman in br.find_elements_by_tag_name("tr"): br.execute_script("arguments[0].setAttribute('class','')", eleman) ogrenciler = [] hesler = [] sorunlar = [] if len(pozitifler) > 0: self.sorguSonucuLabel.setText("Sorun var!") #hes_kodu, tc_no, açıklama tumBilgiler = [ i.text for i in pozitifler[0].find_elements_by_tag_name("td") ] #*Bunlar edevletten gelecek sonuçlar. tmp_hesler = [ i for i in tumBilgiler if tumBilgiler.index(i) % 3 == 0 ] tmp_sorunlar = [ i for i in tumBilgiler if tumBilgiler.index(i) % 3 == 2 ] #*Sınıf sorgulandığı için hesler zaten veritabanında kayıtlı. #Bu sorguda sorun çıkarsa döngü ile veritabanından sorgulanabilir. tmp_ogrenciler = vt.DB.hes_kodu_listesi_ile(hesler) if len(tmp_ogrenciler) > 0: for ogrenci in tmp_ogrenciler: if ogrenci[SINIF_INDEX] == sinif: ind = tmp_ogrenciler.index(ogrenci) ogrenciler.append(ogrenci) hesler.append(tmp_hesler[ind]) sorunlar.append(tmp_sorunlar[ind]) if len(gecersizler) > 0: self.sorguSonucuLabel.setText("Sorun var!") tumBilgiler = [ i.text for i in gecersizler[0].find_elements_by_tag_name("td") ] tmp_hesler = [ i for i in tumBilgiler if tumBilgiler.index(i) % 3 == 0 ] tmp_sorunlar = [ i for i in tumBilgiler if tumBilgiler.index(i) % 3 == 1 ] #*Sınıf sorgulandığı için hesler zaten veritabanında kayıtlı. #Bu sorguda sorun çıkarsa döngü ile veritabanından sorgulanabilir. tmpOgrenciler = vt.DB.hes_kodu_listesi_ile(tmp_hesler) if len(tmpOgrenciler) > 0: for ogrenci in tmpOgrenciler: if ogrenci[SINIF_INDEX] == sinif: ind = tmpOgrenciler.index(ogrenci) ogrenciler.append(ogrenci) hesler.append(tmp_hesler[ind]) sorunlar.append(tmp_sorunlar[ind]) self.tabloyaGonderilenOgrenciler = ogrenciler self.tabloyaGonderilenSorunlar = sorunlar else: self.sorguSonucuLabel.setText("Sorun yok.") self.tabloGonderButton.click() self.animasyonKapatButon.click() br.close() def tabloIsle(self): if len(self.tabloyaGonderilenOgrenciler) > 0: self.sorguSonucuLabel.setStyleSheet("QLabel{background-color:red}") ogrenciler = self.tabloyaGonderilenOgrenciler sorunlar = self.tabloyaGonderilenSorunlar tablo = self.sorguSonucuTableWidget tablo.setRowCount(len(ogrenciler) + 1) for ogrenci in ogrenciler: sira = ogrenciler.index(ogrenci) + 1 fotoLabel = QLabel() resim = ogrenci[RESIM_INDEX].scaled(45, 50, Qt.KeepAspectRatio) fotoLabel.setPixmap(resim) tablo.setCellWidget(sira, 0, fotoLabel) tablo.setItem( sira, 1, QTableWidgetItem(ogrenci[AD_INDEX] + " " + ogrenci[SOYAD_INDEX])) tablo.setItem(sira, 2, QTableWidgetItem(str(ogrenci[OKUL_NO_INDEX]))) tablo.setItem(sira, 3, QTableWidgetItem(sorunlar[sira - 1])) #* Tablo biçimlendirmeleri tablo.horizontalHeader().setSectionResizeMode( 0, QHeaderView.ResizeToContents) tablo.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) tablo.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) tablo.horizontalHeader().setSectionResizeMode( 3, QHeaderView.Stretch) tablo.verticalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) else: self.sorguSonucuLabel.setStyleSheet( "QLabel{background-color:green}") self.sorguSonucuLabel.setText("Sorun yok") def dosyaSec(self): dosyaAdi, _ = QFileDialog.getOpenFileName( self, 'Dosya seç', '', "Excel files (*.xls *.xlsx)") if dosyaAdi: self.dosyaYoluLineEdit.setText(dosyaAdi) def dizinSec(self): fotoDizin = str(QFileDialog.getExistingDirectory(self, "Dizin seç")) if fotoDizin: self.fotoYoluLineEdit.setText(fotoDizin) def topluKaydet(self): if self.kullaniciAdi.text() == "" or self.sifre.text() == "": self.mesaj = "E-Devlet kullanıcı adı ve şifrenizi girelisiniz." self.hataMesajiButton.click() return if os.path.exists(self.dosyaYoluLineEdit.text()) and os.path.exists( self.fotoYoluLineEdit.text()): #Excelden veriler alınıyor. ogrenciler = self.exceldenVeriAl() #Veritabanına kaydediliyor. hesListesi = [ogrenci[HES_KODU_INDEX] for ogrenci in ogrenciler] self.hesExcelDosyalasiniKaydet(hesListesi) #Tek grup oluşturuldu. Başarılı olursa veritabanına kaydedilecek. #Grup yoksa oluşturulacak varsa üstüne hes kodları eklenecek. self.yukleniyorAnimasyonuBaslat() yol = os.getcwd() + os.sep + OLUSTURULAN_EXCEL_DOSYASI_ADI if len(vt.DB.sinif_isimleri()) == 0: th = Thread(target=self.grupOlustur, args=(E_DEVLET_GRUP_ADI, yol, ogrenciler)) th.start() else: th = Thread(target=self.grupOlustur, args=(E_DEVLET_GRUP_ADI, yol, ogrenciler, "", True)) th.start() else: self.mesaj = "Excel dosyasını ve fotoğraf dizinini seçmelisiniz!" self.hataMesajiButton.click() def exceldenVeriAl(self): dosyaYolu = self.dosyaYoluLineEdit.text() indexler = { "ad": 1, "soyad": 2, "tc_no": 3, "hes": 5, "okul_no": 0, "sinif": 4 } wb = load_workbook(dosyaYolu, read_only=True) ws = wb.active fotoYol = self.fotoYoluLineEdit.text() dosyaIsimleri = os.listdir(fotoYol) dosyaTamIsimleri = [ i for i in dosyaIsimleri if i.endswith(".jpg") or i.endswith(".png") ] veriler = ws.values ogrenciler = [] sayac = -1 for satir in veriler: #Excelde ilk satır başlık satırı. sayac += 1 if sayac == 0: continue ogrenci = [] tmp = [*satir] tc = tmp[indexler["tc_no"]] if tc == None: break ogrenci.append(str(tc)) ad = tmp[indexler["ad"]] ogrenci.append(ad) soyad = tmp[indexler["soyad"]] ogrenci.append(soyad) numara = tmp[indexler["okul_no"]] ogrenci.append(numara) numaraString = str(numara) sinif = tmp[indexler["sinif"]] ogrenci.append(sinif) if numaraString + ".jpg" in dosyaTamIsimleri: resim = fotoYol + "/" + numaraString + ".jpg" elif numaraString + ".png" in dosyaIsimleri: resim = fotoYol + "/" + numaraString + ".png" else: resim = "" ogrenci.append(resim) hes = tmp[indexler["hes"]] ogrenci.append(hes) ogrenci.append(1) ogrenciler.append(ogrenci) wb.close() return ogrenciler def hesExcelDosyalasiniKaydet(self, hesListesi): try: wb = xlsxwriter.Workbook(OLUSTURULAN_EXCEL_DOSYASI_ADI) ws = wb.add_worksheet() ws.write(0, 0, "HES KODU") yazilacak_satir = 1 for hes in hesListesi: ws.write(yazilacak_satir, 0, hes) yazilacak_satir += 1 wb.close() return True except: return False def sinifSilClicked(self): if self.comboboxSinifSec.currentText() == "": self.mesaj = "Silinecek sınıf yok!" self.hataMesaji() return qm = QMessageBox(self) mesaj = f"{self.comboboxSinifSec.currentText()} silinecek. Onaylıyor musunuz?" ret = qm.warning(self, 'Sınıf Sil', mesaj, qm.Yes | qm.No) if ret == qm.Yes: vt.DB.sinif_sil(self.comboboxSinifSec.currentText()) self.btnSinifIslemleri.click() self.mesaj = "Sınıf silindi." self.hataMesajiButton.click()