def __init__(self, parent=None): super(MainWindow, self).__init__(parent=parent) self.threadpool = QThreadPool() self.initUI() self.initList() self.initSearchTab()
def __init__(self, gui, icon, do_user_config): QDialog.__init__(self, gui) self.gui = gui self.do_user_config = do_user_config self.threadpool = QThreadPool() # The current database shown in the GUI # db is an instance of the class LibraryDatabase from db/legacy.py # This class has many, many methods that allow you to do a lot of # things. For most purposes you should use db.new_api, which has # a much nicer interface from db/cache.py self.db = gui.current_db # Window properties self.setWindowTitle('Humble-Bundle Downloader') self.setWindowIcon(icon) # Create main layout self.mainlayout = QHBoxLayout() self.setLayout(self.mainlayout) # Create layout for buttons self.buttonlayout = QVBoxLayout() self.mainlayout.addLayout(self.buttonlayout) # Add label self.label = QLabel('') self.buttonlayout.addWidget(self.label) # Add config button self.conf_button = QPushButton('Configure', self) self.conf_button.clicked.connect(self.config) self.buttonlayout.addWidget(self.conf_button) # Add Sync button self.Import_button = QPushButton('Import', self) self.Import_button.clicked.connect(self.Download) self.buttonlayout.addWidget(self.Import_button) # Add 'about' button self.about_button = QPushButton('About', self) self.about_button.clicked.connect(self.about) self.buttonlayout.addWidget(self.about_button) # Add log pane self.textlog = QTextEdit(self) self.mainlayout.addWidget(self.textlog) self.textlog.setReadOnly(True) self.refresh_label() self.check_field_exists() self.resize(800, 200)
def __init__(self, path=None): self._image_queue = QueueService() self._classified_images = list() self.current_image = None self._next_image = None self.num_classified_single = 0 self.num_classified_multi = 0 self._thread_pool = QThreadPool() if path: self.load_images(path)
def __delete__(self): self._isClosing = True IconProvider.instance().saveIconsToDatabase() # Wait for all QtConcurrent jobs to finish QThreadPool.globalInstance().waitForDone() # Delete all classes that are saving data in destructor self._bookmarks = None self._cookieJar = None Settings.syncSettings()
def pushButton_4_Click(self): self.close_mpl() self.replot_now() V1 = self.coin_dict['toss_coin1'] V2 = self.coin_dict['toss_coin2'] D = np.hstack((V1, V2)) D.tolist().sort() k1 = choice(D) #隨機選2個不重複的中心k1, k2 k2 = choice(D) while (k1 == k2): k2 = choice(D) do_k_means = Run_k_means(D, k1, k2) #把 D, k1, k2 傳入多線程 do_k_means.res.callback_signal.connect( self.show_k_means_result) #回傳值連接func後續處理 QThreadPool.globalInstance().start(do_k_means) #執行多線程
def pushButton_3_Click(self): filename = self.ui.lineEdit_2.text() res = np.load(filename, allow_pickle=True) np_all_img = res['np_all_img'] wb_all_img = res['wb_all_img'] np_all_t = res['np_all_t'] wb_all_t = res['wb_all_t'] '''原始方法RXD多線程''' do_originalRXD = Run_OriginalRXD(np_all_img, np_all_t) # 傳變數給多線程 do_originalRXD.res.callback_signal.connect( self.drawOriginalRXD) # 將回傳的變數連結給函式處理 QThreadPool.globalInstance().start(do_originalRXD) # 多線程開始工作 '''Woodbury方法RXD多線程''' do_woodburyRXD = Run_WoodburyRXD(wb_all_img, wb_all_t) # 傳變數給多線程 do_woodburyRXD.res.callback_signal.connect( self.drawWoodburyRXD) # 將回傳的變數連結給函式處理 QThreadPool.globalInstance().start(do_woodburyRXD) # 多線程開始工作
def __init__(self, parent=None): super().__init__(parent) self._subService = OpenSubService() self._encService = EncodingService() self._token = None self._threadPool = QThreadPool.globalInstance() self._initUi() self._restoreWindowSettings()
def initUI(self): grid = QGridLayout() grid.setVerticalSpacing(0.5) self.setLayout(grid) self.timer_lbl = QLabel(self) font = QFont('Courier New') font.setBold(True) font.setPointSize(70) self.timer_lbl.setFont(font) grid.addWidget(self.timer_lbl, 0, 0, 3, 2, Qt.AlignCenter) self.main_btn = QPushButton('Start', self) self.main_btn.clicked.connect(self.on_click_main_btn) grid.addWidget(self.main_btn, 0, 3, 1, 1) self.skip_btn = QPushButton('Skip', self) self.skip_btn.clicked.connect(self.on_click_skip_btn) grid.addWidget(self.skip_btn, 1, 3, 1, 1) self.reset_btn = QPushButton('Reset', self) self.reset_btn.clicked.connect(self.on_click_reset_btn) grid.addWidget(self.reset_btn, 2, 3, 1, 1) self.dropdown = QComboBox() self.dropdown.setMinimumWidth(250) self.dropdown.setMaximumWidth(250) self.dropdown.currentIndexChanged.connect(self.on_change_select_task) grid.addWidget(self.dropdown, 4, 0, Qt.AlignCenter) self.complete_btn = QPushButton('Completed', self) self.complete_btn.clicked.connect(self.on_click_complete_btn) grid.addWidget(self.complete_btn, 4, 3, 1, 1) self.threadpool = QThreadPool() self.update_timer_lbl() self.refresh_dropdown()
class HBDDialog(QDialog): restart_required = False def __init__(self, gui, icon, do_user_config): QDialog.__init__(self, gui) self.gui = gui self.do_user_config = do_user_config self.threadpool = QThreadPool() # The current database shown in the GUI # db is an instance of the class LibraryDatabase from db/legacy.py # This class has many, many methods that allow you to do a lot of # things. For most purposes you should use db.new_api, which has # a much nicer interface from db/cache.py self.db = gui.current_db # Window properties self.setWindowTitle('Humble-Bundle Downloader') self.setWindowIcon(icon) # Create main layout self.mainlayout = QHBoxLayout() self.setLayout(self.mainlayout) # Create layout for buttons self.buttonlayout = QVBoxLayout() self.mainlayout.addLayout(self.buttonlayout) # Add label self.label = QLabel('') self.buttonlayout.addWidget(self.label) # Add config button self.conf_button = QPushButton('Configure', self) self.conf_button.clicked.connect(self.config) self.buttonlayout.addWidget(self.conf_button) # Add Sync button self.Import_button = QPushButton('Import', self) self.Import_button.clicked.connect(self.Download) self.buttonlayout.addWidget(self.Import_button) # Add 'about' button self.about_button = QPushButton('About', self) self.about_button.clicked.connect(self.about) self.buttonlayout.addWidget(self.about_button) # Add log pane self.textlog = QTextEdit(self) self.mainlayout.addWidget(self.textlog) self.textlog.setReadOnly(True) self.refresh_label() self.check_field_exists() self.resize(800, 200) def check_field_exists(self): db = self.db.new_api if HBDDialog.restart_required: self.textlog.append('Restart required before plugin can be used.') elif '#humble_filenames' in db.get_categories(): self.textlog.append('#humble_filenames field exists.') else: self.textlog.append('#humble_filenames field does not exist...') self.add_field() def add_field(self): # Reference at # https://github.com/kovidgoyal/calibre/blob/master/src/calibre/gui2/preferences/create_custom_column.py db = self.gui.library_view.model().db col = 'humble_filenames' col_heading = 'Original HB filenames' col_type = 'text' is_multiple = True display_dict = { 'description': 'Original filenames of ebooks downloaded via the HB Downloader plugin' } db.create_custom_column(label=col, name=col_heading, datatype=col_type, is_multiple=is_multiple, display=display_dict) HBDDialog.restart_required = True self.textlog.append( 'The field has been created and will be usable after a restart.') self.refresh_label() def refresh_label(self): if HBDDialog.restart_required: self.label.setText('Calibre restart required') self.Import_button.setEnabled(False) elif prefs['cookie_auth_token'] == '': self.label.setText('Authentication token not set.') self.Import_button.setEnabled(False) else: self.label.setText('Authentication token set.') self.Import_button.setEnabled(True) def Download(self): db = self.db.new_api auth_token = prefs['cookie_auth_token'] dl_loc = prefs['download_loc'] log = self.textlog I = importer(db, auth_token, dl_loc) I.signals.log.connect(self.textlog.append) I.signals.done_downloads.connect(self.Import) self.threadpool.start(I) def Import(self, download_names): paths = [prefs['download_loc'] + name for name in download_names] Adder(paths, db=self.gui.current_db, parent=self.gui, pool=self.gui.spare_pool()) def config(self): self.do_user_config(parent=self) self.refresh_label() self.textlog.append('Config changed.') def about(self): text = get_resources('about.txt') QMessageBox.about(self, 'About Humble-Bundle downloader', text.decode('utf-8'))
class ImageService: def __init__(self, path=None): self._image_queue = QueueService() self._classified_images = list() self.current_image = None self._next_image = None self.num_classified_single = 0 self.num_classified_multi = 0 self._thread_pool = QThreadPool() if path: self.load_images(path) # if no path was supplied load_images(path) has to be called, before working with ImageService! @property def num_images_to_classify(self): return len(self._image_queue) @property def done(self): return self.num_images_to_classify == 0 and not self.current_image def load_images(self, path): image_data_array = FileService().read_h5_file(path) for id, image_data in enumerate(image_data_array): self._image_queue.enqueue(Image(id, image_data)) self._image_queue.shuffle() self._get_next_image() def _get_next_image(self): if self._next_image: self.current_image = self._next_image self._image_queue.dequeue() else: self.current_image = self._image_queue.dequeue() try: self._preload_next_image() except: pass def _preload_next_image( self ): # preloads next image in queue into memory in a different thread self._next_image = self._image_queue.peek() self._thread_pool.start( ThreadingService(PlotService().convert_to_image, image=self._next_image)) def skip_image(self): self._image_queue.enqueue(self.current_image) self._get_next_image() def classify_image(self, category): if category == 'single': self.num_classified_single += 1 elif category == 'multi': self.num_classified_multi += 1 self.current_image.classify(category) self._classified_images.append(self.current_image) try: self._get_next_image() except: self.current_image = None def save_results(self, path=Defaults.output_path): output = 'image_id,category\n' for image in sorted(self._classified_images, key=lambda img: img.id): output += '{},{}\n'.format(image.id, image.classification) FileService().write_csv_file(path, output)
class MainWindow(QWidget): def __init__(self, controller): super().__init__() self.controller = controller self._pomo_start_ts = None self._current_dropdown_tasks = [] self._taskw_sel_task = None self.initUI() def initUI(self): grid = QGridLayout() grid.setVerticalSpacing(0.5) self.setLayout(grid) self.timer_lbl = QLabel(self) font = QFont('Courier New') font.setBold(True) font.setPointSize(70) self.timer_lbl.setFont(font) grid.addWidget(self.timer_lbl, 0, 0, 3, 2, Qt.AlignCenter) self.main_btn = QPushButton('Start', self) self.main_btn.clicked.connect(self.on_click_main_btn) grid.addWidget(self.main_btn, 0, 3, 1, 1) self.skip_btn = QPushButton('Skip', self) self.skip_btn.clicked.connect(self.on_click_skip_btn) grid.addWidget(self.skip_btn, 1, 3, 1, 1) self.reset_btn = QPushButton('Reset', self) self.reset_btn.clicked.connect(self.on_click_reset_btn) grid.addWidget(self.reset_btn, 2, 3, 1, 1) self.dropdown = QComboBox() self.dropdown.setMinimumWidth(250) self.dropdown.setMaximumWidth(250) self.dropdown.currentIndexChanged.connect(self.on_change_select_task) grid.addWidget(self.dropdown, 4, 0, Qt.AlignCenter) self.complete_btn = QPushButton('Completed', self) self.complete_btn.clicked.connect(self.on_click_complete_btn) grid.addWidget(self.complete_btn, 4, 3, 1, 1) self.threadpool = QThreadPool() self.update_timer_lbl() self.refresh_dropdown() @log_call def on_click_main_btn(self, _): if self.main_btn.text() == 'Start': self.start_session() else: self.stop_session() @log_call def on_click_complete_btn(self, _): self.stop_session() self.controller.taskw.complete_task(self._taskw_sel_task) self.refresh_dropdown() @log_call def on_click_skip_btn(self, _): self.controller.pomo.skip() self.update_timer_lbl() @log_call def on_click_reset_btn(self, _): self.controller.pomo.reset() self.update_timer_lbl() @log_call def on_change_select_task(self, i): self._taskw_sel_task = self._current_dropdown_tasks[i] log.info('Changed selected task to "%s"', self._taskw_sel_task.description) @log_call def start_session(self): for component in [ self.complete_btn, self.skip_btn, self.reset_btn, self.dropdown ]: component.setEnabled(False) if self.controller.pomo.is_work_task: # self.complete_btn.setEnabled(True) self.threadpool.start( Worker(self.controller.taskw.start_task, self._taskw_sel_task)) self.threadpool.start( Worker(self.controller.slack.enable_dnd, n_min=self.controller.pomo.current.value // 60)) self._pomo_start_ts = datetime.datetime.now() self.main_btn.setText('Stop') @log_call def stop_session(self): for component in [ self.complete_btn, self.skip_btn, self.reset_btn, self.dropdown ]: component.setEnabled(True) if self.controller.taskw.is_running: self.threadpool.start( Worker(self.controller.taskw.stop_task, self._taskw_sel_task)) self.threadpool.start(Worker(self.controller.slack.disable_dnd)) self._pomo_start_ts = None self.main_btn.setText('Start') @log_call def refresh_dropdown(self): if self._pomo_start_ts is None: log.info('Considering a dropdown list refresh') self.controller.taskw.refresh() new_tasks = self.controller.taskw.tasks if new_tasks != self._current_dropdown_tasks: log.info('Refreshing dropdown list') self._current_dropdown_tasks = new_tasks self.dropdown.clear() self.dropdown.addItems( [t.description for t in self._current_dropdown_tasks]) @log_call def update_timer_lbl(self): pomo = datetime.timedelta(seconds=self.controller.pomo.current.value) log.debug('Current pomodoro time: %s', pomo) if self._pomo_start_ts: pomo = (self._pomo_start_ts + pomo) - datetime.datetime.now() self.timer_lbl.setText("{:02}:{:02}".format(pomo.seconds // 60, pomo.seconds % 60)) if pomo.seconds <= 0: self.threadpool.start(Worker(self.controller.pomo.complete)) self.stop_session()
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent=parent) self.threadpool = QThreadPool() self.initUI() self.initList() self.initSearchTab() def initUI(self): self.tabWidget = QTabWidget(self) self.searchEngine = SearchEngine() self.setGeometry(0, 0, 495, 635) self.center() self.setCentralWidget(self.tabWidget) self.status = self.statusBar() self.mainMenu = self.menuBar() exitAct = QAction('&Exit', self) exitAct.setShortcut('Ctrl+Q') exitAct.setStatusTip('Exit application') exitAct.triggered.connect(qApp.quit) exportList = QAction('Export &List',self) exportList.setShortcut('Ctrl+L') exportList.setStatusTip('Export your manga list(backup)') reloadList = QAction('Reload list',self) reloadList.setShortcut('Ctrl+R') reloadList.triggered.connect(self.loadManga) fileMenu = self.mainMenu.addMenu('&File') fileMenu.addAction(exportList) fileMenu.addAction(reloadList) fileMenu.addAction(exitAct) def eventFilter(self, source, event): if (event.type() == QtCore.QEvent.ContextMenu and source is self.searchResults): menu = QMenu() infoAction = QAction('Info',self) infoAction.setStatusTip('Show information about this manga title') infoAction.triggered.connect(self.showMangaInfo) addMangaAction = QAction('Add to list',self) addMangaAction.triggered.connect(self.addToList) menu.addAction(infoAction) menu.addAction(addMangaAction) menu.exec_(event.globalPos()) return True return super(QMainWindow, self).eventFilter(source, event) def center(self): qr = self.frameGeometry() cp = QDesktopWidget().availableGeometry().center() qr.moveCenter(cp) self.move(qr.topLeft()) def loadManga(self): self.mainLayout.clearList() jsonObject = json.loads(open('mangalist.json').read()) for manga in jsonObject['Manga']: manga = Series(self,manga['imagePath'],manga['title']) self.mainLayout.addWidget(manga) def initSearchTab(self): box = QVBoxLayout(self.tabWidget) widget = QWidget(self.tabWidget) self.inputLine = QLineEdit(widget) self.inputLine.returnPressed.connect(self.searchRequest) self.inputLine.setPlaceholderText("Search for a manga title") self.inputLine.setClearButtonEnabled(True) self.searchResults = QListWidget(widget) self.searchResults.setFont(QtGui.QFont('sans-serif', 10, 650)) self.searchResults.installEventFilter(self) box.addWidget(self.inputLine) box.addWidget(self.searchResults) widget.setLayout(box) self.tabWidget.addTab(widget, "Search") def executeThread(self): self.worker = Worker(self.addToList) self.worker.signals.finished.connect(self.threadFinished) self.threadpool.start(self.worker) def threadFinished(self): self.loadManga() def addToList(self): url = self.searchResults.currentItem().data(QtCore.Qt.UserRole) self.statusBar().showMessage("Adding Manga to list.") driver = webdriver.PhantomJS() driver.get(url) soup = bs4.BeautifulSoup(driver.page_source,'lxml') title = soup.select('.tabletitle') imageUrl = soup.select('.img-fluid') image = open('images/'+title[0].text,'wb') image.write(requests.get(imageUrl[2]['src']).content) print(imageUrl[2]) image.close() imagePath = 'images/'+title[0].text description = driver.find_element_by_class_name('sContent') item = {"title": "#","description":"#","imagePath":"#"} item["title"] =title[0].text item["description"]=description.text item["imagePath"]=imagePath config = json.loads(open('mangalist.json').read()) config["Manga"].append(item) with open('mangalist.json','w') as f: f.write(json.dumps(config,indent=4)) f.close() self.statusBar().showMessage("Manga added.",0.5) self.loadManga() def showMangaInfo(self): print(self.searchResults.currentItem().text()) def searchRequest(self): resultList = self.searchEngine.search(self.inputLine.text()) self.inputLine.clear() self.searchResults.clear() for result in resultList: item = QListWidgetItem(result['title']) item.setData(QtCore.Qt.UserRole,result['url']) self.searchResults.addItem(item) def initList(self): self.mainArea = QScrollArea(self) self.mainArea.setWidgetResizable(True) mangaWidget = QWidget(self.mainArea) self.mainLayout = FlowLayout(mangaWidget) self.loadManga() self.mainArea.setWidget(mangaWidget) self.tabWidget.addTab(self.mainArea, "MangaList")