def copy(self): cb = QClipboard() try: cb.setText(self.ip) lable except: self.fouceEx()
class About(QDialog): def __init__(self, config, icon=None): super().__init__() self.config = config if icon: self.setWindowIcon(icon) # info panel about_html = self.generate_about_html(html_template) self.about = QTextBrowser() self.about.setOpenExternalLinks(True) self.about.setMinimumSize(400, 260) self.about.setHtml(about_html) # widgets self.clipboard = QClipboard(self) self.status_bar = QLabel() copy_button = QPushButton("Copy") copy_button.setMaximumWidth(75) copy_button.clicked.connect(self.copy_to_clipboard) close_button = QPushButton("Close") close_button.setMaximumWidth(75) close_button.clicked.connect(self.close) # layoyut clipboard_layout = QHBoxLayout() clipboard_layout.addWidget(self.status_bar) clipboard_layout.addWidget(copy_button) clipboard_layout.addWidget(close_button) # Create main layout and add widgets main_layout = QVBoxLayout() main_layout.addWidget(self.about) main_layout.addLayout(clipboard_layout) self.setLayout(main_layout) def generate_about_html(self, html_template): html = html_template html = html.replace('{{product_name}}', self.config["product_name"]) html = html.replace('{{version}}', self.config["version"]) html = html.replace('{{home_page}}', self.config["home_page"]) html = html.replace('{{database_path}}', self.config["database_path"]) html = html.replace('{{preferences_path}}', self.config["preferences_path"]) html = html.replace('{{install_dir}}', self.config["install_dir"]) html = html.replace('{{logs_dir}}', self.config["logs_dir"]) return html def copy_to_clipboard(self): logger.debug('copying text from "About" dialog into clipboard') self.clipboard.setText(self.about.toPlainText()) self.status_bar.setText("Copied into clipboard") self.status_bar.setStyleSheet("font-family: arial; color: #4169e1;")
class ClipboardHelper(QObject): """ Simple wrapper around a QClipboard with methods exposed as Slots for QML use. """ def __init__(self, parent=None): super(ClipboardHelper, self).__init__(parent) self._clipboard = QClipboard(parent=self) @Slot(str) def setText(self, value): self._clipboard.setText(value) @Slot() def clear(self): self._clipboard.clear()
def copy_nodes(self, nodes=None): """ copy nodes to the clipboard by default this method copies the selected nodes from the node graph. Args: nodes (list[NodeGraphQt.Node]): list of node instances. """ nodes = nodes or self.selected_nodes() if not nodes: return False clipboard = QClipboard() serial_data = self._serialize(nodes) serial_str = json.dumps(serial_data) if serial_str: clipboard.setText(serial_str) return True return False
class MainWindow(QMainWindow): """Main Window of the application""" def __init__(self): super().__init__() self.schedule_object = None self.init_ui() self.setStyleSheet(WINDOW_STYLE) self.setWindowTitle("NRC a iCalendar") self.setWindowIcon(QIcon(get_path("assets", "icon.svg"))) self.clikboard = QClipboard() # Dialogo para guardar el archivo self.save_dialog = QFileDialog(self) self.save_dialog.setFileMode(QFileDialog.AnyFile) self.save_dialog.setNameFilter("iCalendar (*.ics)") self.save_dialog.setDefaultSuffix("ics") self.save_dialog.setAcceptMode(QFileDialog.AcceptSave) def init_ui(self): """Makes the layout""" # Barra de opciones y links de interés menu_bar = self.menuBar() options_menu = menu_bar.addMenu("&Opciones") act_allways_visible = options_menu.addAction("Siempre visible") act_allways_visible.setCheckable(True) act_allways_visible.toggled.connect(self.__allways_visible) uc_calendars_menu = menu_bar.addMenu("&Calendarios") for name, link in OTHER_CALENDARS: calendar_option = uc_calendars_menu.addAction(name) # TODO: Ni idea pq se necesita tener una variable `s`, sin esta no funciona calendar_option.triggered.connect( lambda s=None, l=link: self.__to_clipboard(l)) go_to_menu = menu_bar.addMenu("&Ir a") go_to_options = [ ("Feed del calendario de Canvas", "https://cursos.canvas.uc.cl/calendar"), ( "Importar calendario a Google", "https://calendar.google.com/calendar/a/uc.cl/r/settings/export", ), ] for name, link in go_to_options: new_option = go_to_menu.addAction(name) new_option.triggered.connect( lambda s=None, l=link: webbrowser.open(l)) # Main widget main_widget = QFrame() self.setCentralWidget(main_widget) main_layout = QVBoxLayout(main_widget) main_widget.setLayout(main_layout) main_layout.setSizeConstraint(QLayout.SetMinimumSize) # Lista de códigos a ingresar code_layout = QHBoxLayout() main_layout.addLayout(code_layout) self.code_list = [QLineEdit(main_widget) for i in range(6)] code_validator = QIntValidator(main_layout, 10**4, 10**5) for code in self.code_list: code.setObjectName("code_field") code.setAlignment(Qt.AlignCenter) code.setMaxLength(5) code.setValidator(code_validator) code.textEdited.connect(self.check_codes) code_layout.addWidget(code) self.get_button = QPushButton("Obtener horario", main_widget) self.get_button.clicked.connect(self.get_schedule) self.get_button.setCursor(Qt.PointingHandCursor) self.get_button.setDisabled(True) main_layout.addWidget(self.get_button) self.schedule_view = ScheduleView(8, 6, main_widget) main_layout.addWidget(self.schedule_view) self.save_button = QPushButton("Guardar horario", main_widget) self.save_button.clicked.connect(self.save_schedule) self.save_button.setCursor(Qt.PointingHandCursor) self.save_button.setDisabled(True) main_layout.addWidget(self.save_button) self.status_bar = QStatusBar(self) self.status_bar.showMessage("Ingrese los códigos NRC") self.setStatusBar(self.status_bar) self.adjustSize() def __allways_visible(self, option): flags = self.windowFlags() if option: self.setWindowFlags(flags | Qt.WindowStaysOnTopHint) else: self.setWindowFlags(flags ^ Qt.WindowStaysOnTopHint) self.show() def __to_clipboard(self, link): self.clikboard.setText(link) self.status_bar.showMessage( "URL del calendario copiado a portapapeles") def check_codes(self): """Check if the codes are valid""" at_least_one_valid = False for code in self.code_list: if valid_nrc(code.text()): at_least_one_valid = True elif code.text(): # TODO: cambiar el estilo al ser invalido y tener texto pass else: pass self.get_button.setDisabled(not at_least_one_valid) if at_least_one_valid: self.status_bar.clearMessage() else: self.status_bar.showMessage("Ingrese los códigos NRC") def get_schedule(self): """Get the schedule of Buscacursos UC""" valid_codes = list( filter(valid_nrc, map(QLineEdit.text, self.code_list))) if not valid_codes: return try: self.schedule_object = Schedule.get(valid_codes) except OSError: error_box = QMessageBox(QMessageBox.Critical, "Error", "No se ha podido importar el horario") error_box.exec_() else: self.show_schedule() def show_schedule(self): """Show the schedule in the table""" # Limpia el horario self.schedule_view.clearContents() # Si no hay módulos, se deshabilita la opción de guardar y termina if not self.schedule_object.courses: self.schedule_view.update_size() self.save_button.setDisabled(True) return # Si existen módulos, se muestran en el horario for i_row, row in enumerate(self.schedule_object.get_table()): for sub_row in row: for i_col, element in enumerate(sub_row): if not element: continue module_label = QLabel(self.schedule_view) module_label.setText(element.code) module_label.setObjectName(element.type_) module_label.setAlignment(Qt.AlignCenter) module_label.setFixedHeight(20) cell_frame = self.schedule_view.cellWidget(i_row, i_col) # Se crea un frame para los widgets si no existe if not cell_frame: cell_frame = QFrame(self.schedule_view) cell_layout = QVBoxLayout(cell_frame) cell_layout.setSpacing(0) cell_layout.setMargin(0) self.schedule_view.setCellWidget( i_row, i_col, cell_frame) cell_frame.layout().addWidget(module_label) self.schedule_view.update_size() self.save_button.setDisabled(False) def save_schedule(self): """Saves the schedule""" if self.save_dialog.exec_(): out_dir = self.save_dialog.selectedFiles()[0] with open(out_dir, mode="w", encoding="utf-8") as file: file.write(self.schedule_object.to_ics())