class _ResponsesTab(QTabWidget): """Tab which shows all module and shell responses.""" def __init__(self): super().__init__() layout = QVBoxLayout() self._output_field = QTextEdit() self._output_field.setTextInteractionFlags(Qt.NoTextInteraction) self._output_field.setPlaceholderText("Please wait for responses...") layout.addWidget(self._output_field) self.setLayout(layout) def clear(self): """Clears all output.""" self._output_field.clear() def output(self, text: str): """Adds a line to the output field.""" self._output_field.append(text)
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 MainWindow(QMainWindow): def __init__(self, src, dest): QMainWindow.__init__(self) self.setMinimumSize(QSize(640, 160)) self.setWindowTitle("Copy Images") self.centralWidget = QWidget(self) self.setCentralWidget(self.centralWidget) self.layout = QVBoxLayout(self.centralWidget) self.source = QPushButton("Select src file (.txt list file of images)") self.layout.addWidget(self.source) self.source.released.connect(self.selectSource) self.destination = QPushButton( "Select dest folder to copy the images to") self.layout.addWidget(self.destination) self.destination.released.connect(self.selectDestination) run = QPushButton("Start copy process") self.layout.addWidget(run) run.released.connect(self.copyFiles) self.textOutput = QTextEdit() self.layout.addWidget(self.textOutput) self.sourcePath = None self.destinationPath = None if None != src: self.selectSource(src) if None != dest: self.selectDestination(dest) self.copyThread = copyThread(src, dest) self.copyThread.newText.connect(self.writeText) def selectSource(self, src=None): if src == None: self.sourcePath, _ = QFileDialog.getOpenFileName( None, 'Choose the file to work with', '', 'Image list .txt (*.txt);; * (*.*)', '') else: self.sourcePath = src self.source.setText("Source: " + self.sourcePath) self.textOutput.append("Source selected: " + self.sourcePath) def selectDestination(self, dest=None): if dest == None: self.destinationPath = QFileDialog.getExistingDirectory( self, 'Choose the destination to copy to', '') else: self.destinationPath = dest self.destination.setText("Destination: " + self.destinationPath) self.textOutput.append("Destination: " + self.destinationPath) def copyFiles(self): if self.sourcePath is not None and self.destinationPath is not None: self.copyThread.sourcePath = self.sourcePath self.copyThread.destinationPath = self.destinationPath self.copyThread.start() else: self.textOutput.append( 'Please select a source file and a destination folder.') def writeText(self, line): self.textOutput.append(line) self.textOutput.ensureCursorVisible()
class MyWidget(QWidget): log = Logger('logs/main/main.log', level='info') METHOD_KERNEL = Kernel(log.logger) def __init__(self, Parant=None): super().__init__(Parant) self.__eraser_mode_set = False self.__init_data() self.__init_view() def __init_data(self): self.__canvas = PaintBoard(self) self.__colorList = QColor.colorNames() def __init_view(self): self.setFixedSize(720, 530) self.label_university = QLabel("学校:\t华南理工大学", self) self.label_university.setStyleSheet("font-size:12px") self.label_university.setGeometry(460, 10, 120, 35) self.label_school = QLabel("专业:\t控制科学与工程", self) self.label_school.setStyleSheet("font-size:12px") self.label_school.setGeometry(460, 40, 140, 35) self.label_name = QLabel("姓名:\t***", self) self.label_name.setStyleSheet("font-size:12px") self.label_name.setGeometry(460, 70, 100, 35) self.label_number = QLabel("学号:\t***", self) self.label_number.setStyleSheet("font-size:12px") self.label_number.setGeometry(460, 100, 120, 35) self.label_im = QLabel(self) self.label_im.setGeometry(600, 20, 105, 105) self.label_im.setPixmap(QPixmap("./im_scut.jpg").scaled(105, 105)) self.label_log = QTextEdit(self) self.label_log.setReadOnly(True) # self.label_log.moveCursor(QTextCursor.Down) self.label_log.setStyleSheet( "background:transparent; font-size:15px; font-family:Roman times") # self.label_log.resize(220, 200) self.label_log.setGeometry(460, 140, 245, 220) self.label_log.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.label_log.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) # create a horizontal layout as the main layout of the GUI main_layout = QHBoxLayout(self) # set the distance between widgets to 10px main_layout.setSpacing(10) left_layout = QVBoxLayout() left_layout.setContentsMargins(5, 5, 5, 5) left_layout.addWidget(self.__canvas) path_layout = QHBoxLayout() path_layout.setContentsMargins(5, 5, 5, 5) self.__lab_path = QLabel(self) self.__lab_path.setText("Save Path") self.__lab_path.setFixedHeight(10) path_layout.addWidget(self.__lab_path) left_layout.addLayout(path_layout) self.__txt_path = QLineEdit("./data/1") path_layout.addWidget(self.__txt_path) self.__choose_path = QPushButton("index") self.__choose_path.setParent(self) # self.__choose_path.setShortcut("Ctrl+S") self.__choose_path.clicked.connect(self.btn_save_clicked) path_layout.addWidget(self.__choose_path) btn_layout = QHBoxLayout() btn_layout.setContentsMargins(5, 5, 5, 5) self.__btn_save = QPushButton("Save") self.__btn_save.setParent(self) self.__btn_save.setShortcut("Ctrl+A") self.__btn_save.clicked.connect(self.save_image) btn_layout.addWidget(self.__btn_save) self.__btn_recognize = QPushButton("Predict") self.__btn_recognize.setParent(self) self.__btn_recognize.setShortcut("Ctrl+R") self.__btn_recognize.clicked.connect(self.btn_recog_clicked) btn_layout.addWidget(self.__btn_recognize) self.__btn_clear = QPushButton("Clear") self.__btn_clear.setShortcut("Ctrl+X") self.__btn_clear.setParent(self) self.__btn_clear.clicked.connect(self.btn_clear_clicked) btn_layout.addWidget(self.__btn_clear) self.__btn_exit = QPushButton("EXIT") self.__btn_exit.setParent(self) # self.__btn_exit.setShortcut("Ctrl+Q") self.__btn_exit.clicked.connect(self.btn_exit_clicked) btn_layout.addWidget(self.__btn_exit) left_layout.addLayout(btn_layout) main_layout.addLayout(left_layout) # put canvas in the left GUI # main_layout.addWidget(self.__canvas) # main_layout.addWidget(left_layout) # set the right layout right_layout = QVBoxLayout() # set the space between right contents right_layout.setContentsMargins(5, 5, 5, 14) splitter = QSplitter(self) right_layout.addWidget(splitter) method_layout = QHBoxLayout() self.__lab_method = QLabel(self) self.__lab_method.setText("Recognition Method") self.__lab_method.setFixedHeight(30) method_layout.addWidget(self.__lab_method) self.kernel_list = [ 'NaiveBayesian', 'VoteFisher', 'MultiFisher', 'SklearnFisher', 'CNN' ] self.__box_method = QComboBox(self) self.__box_method.addItems(self.kernel_list) self.__box_method.setCurrentIndex(0) method_layout.addWidget(self.__box_method) right_layout.addLayout(method_layout) show_layout = QHBoxLayout() canv_layout = QVBoxLayout() self.__cbtn_eraser = QCheckBox("Eraser") self.__cbtn_eraser.setParent(self) self.__cbtn_eraser.clicked.connect(self.btn_eraser_clicked) canv_layout.addWidget(self.__cbtn_eraser) pen_size_layout = QHBoxLayout() self.__lab_pen_size = QLabel(self) self.__lab_pen_size.setText("Pen Size") self.__lab_pen_size.setFixedHeight(20) # self.__lab_pen_size.setFixedSize(50, 20) pen_size_layout.addWidget(self.__lab_pen_size) self.__box_pen_size = QSpinBox(self) self.__box_pen_size.setMaximum(40) self.__box_pen_size.setMinimum(20) self.__box_pen_size.setValue(30) self.__box_pen_size.setSingleStep(2) self.__box_pen_size.setFixedSize(50, 20) self.__box_pen_size.valueChanged.connect(self.box_pen_size_change) pen_size_layout.addWidget(self.__box_pen_size) canv_layout.addLayout(pen_size_layout) pen_color_layout = QHBoxLayout() self.__label_pen_color = QLabel(self) self.__label_pen_color.setText("Pen Color") self.__label_pen_color.setFixedHeight(20) pen_color_layout.addWidget(self.__label_pen_color) self.__combo_pen_color = QComboBox(self) self.__combo_pen_color.setFixedSize(50, 20) self.__fillColorList(self.__combo_pen_color) self.__combo_pen_color.currentIndexChanged.connect( self.pen_color_changed) pen_color_layout.addWidget(self.__combo_pen_color) canv_layout.addLayout(pen_color_layout) show_layout.addLayout(canv_layout) self.feature_map = QLabel() self.feature_map.setFixedSize(100, 100) self.feature_map.setText("") self.feature_map.setObjectName('feature map') show_layout.addWidget(self.feature_map) right_layout.addLayout(show_layout) main_layout.addLayout(right_layout) def btn_recog_clicked(self): self.update() savePath = "./recog.jpg" image = self.__canvas.get_current_image() image.save(savePath) save_path = os.path.abspath(savePath) self.label_log.append("image saved in path:\n{}".format(save_path)) method_text = self.__box_method.currentText() self.label_log.append('method: {}'.format(method_text)) predict = self.METHOD_KERNEL.set_kernel(savePath, method_text) # pic = QTextImageFormat() # pic.setName('./feature_map.jpg') # pic.setHeight(100) # pic.setWidth(100) showImage = QImage('./feature_map.jpg').scaled(100, 100) self.feature_map.setPixmap(QPixmap.fromImage(showImage)) # self.label_log.append('feature map:\n') # self.label_log.textCursor().insertImage('./feature_map.jpg') self.label_log.append("recognition result is: {}".format(predict)) # self.label_log.moveCursor(QTextCursor.End) # self.label_log.textCursor().clearSelection() # del pic message = QMessageBox() message.setText("recognition result is: {}".format(predict)) # message.addButton() message.exec_() def btn_clear_clicked(self): self.__canvas.clear() self.label_log.append("Canvas is clean now!") def btn_save_clicked(self): save_path = QFileDialog.getSaveFileName(self, 'save your paint', '.\\', '*.jpg') if save_path[0] == "": self.label_log.append("save cancel") return self.__txt_path.setText(save_path[0]) save_image = self.__canvas.get_current_image() save_image.save(save_path[0]) save_path_ = os.path.abspath(save_path[0]) self.label_log.append("image saved in path:\n{}".format(save_path_)) def save_image(self): self.__txt_path.setText(self.__txt_path.displayText()) save_path = self.__txt_path.text() created = create_dir_path(save_path) if created: self.label_log.append("create an directory:\n{}".format(save_path)) file_path = create_file_path(save_path) save_image = self.__canvas.get_current_image() save_image.save(file_path) file_path_ = os.path.abspath(file_path) self.label_log.append("image saved in path:\n{}".format(file_path_)) def btn_exit_clicked(self): self.close() QApplication.quit() def btn_eraser_clicked(self): self.__eraser_mode_set = ~self.__eraser_mode_set if self.__eraser_mode_set: self.label_log.append("Attention! Eraser Mode!") else: self.label_log.append("Writing Mode!") if self.__cbtn_eraser.isChecked(): self.__canvas.EraserMode = True else: self.__canvas.EraserMode = False def box_pen_size_change(self): pen_size = self.__box_pen_size.value() self.__canvas.pen_size(pen_size) def __fillColorList(self, comboBox): index_black = 0 index = 0 for color in self.__colorList: if color == "black": index_black = index index += 1 pix = QPixmap(70, 20) pix.fill(QColor(color)) comboBox.addItem(QIcon(pix), None) comboBox.setIconSize(QSize(70, 20)) comboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents) comboBox.setCurrentIndex(index_black) def pen_color_changed(self): color_index = self.__combo_pen_color.currentIndex() color_str = self.__colorList[color_index] self.__canvas.pen_color(color_str)
class HBDDialog(QDialog): def __init__(self, gui, icon, do_user_config): QDialog.__init__(self, gui) self.gui = gui self.do_user_config = do_user_config # 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.Import) 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 '#humble_filename' in db.get_categories(): self.textlog.append('#humble_filename field exists.') else: self.textlog.append('#humble_filename field does not exist.') # TODO Create the field here def refresh_label(self): if 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 Import(self): # Identify any existing books with humblebundle tag db = self.db.new_api existing_hb_filenames = db.all_field_names('#humble_filename') self.textlog.append( str(len(existing_hb_filenames)) + ' existing books from Humble Bundle identified.') # Attempt to authenticate hapi = HumbleApi(prefs['cookie_auth_token']) ConfigData.download_location = prefs['download_loc'] if hapi.check_login(): self.textlog.append('Authentication successful...') else: self.textlog.append( 'Unable to login - check authentication token.') return # Get orders game_keys = hapi.get_gamekeys() self.textlog.append('%s orders/keys found...' % (len(game_keys))) key_downloads = dict() # Get relevant downloads num_books_found = 0 num_new_books = 0 for key in game_keys: humble_downloads = [] order = hapi.get_order(key) for subproduct in order.subproducts or []: for download in subproduct.downloads or []: # Check platform if download.platform != 'ebook': continue for dl_struct in download.download_structs: num_books_found += 1 # Check filename if dl_struct.filename in existing_hb_filenames: continue humble_downloads.append( HumbleDownload(download, dl_struct, order, subproduct, key)) num_new_books += 1 key_downloads[key] = humble_downloads self.textlog.append( '(%s/%s) books found do not already exist in Calibre...' % (num_new_books, num_books_found)) ticker = 0 for key in key_downloads: # Update URL in case of expiry HumbleDownload.update_download_list_url(hapi, key_downloads.get(key)) for hd in key_downloads.get(key): ticker += 1 self.textlog.append('(%s/%s) Downloading %s ...' % (ticker, num_new_books, hd.filename)) hd.download_file() 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'))