diff --git a/README.md b/README.md index 2ac1ab1..5c9ddca 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ + +- `pip install cefpython3` +- `pip install tkhtmlview` +- `pip install PyQt5 PyQtWebEngine` + + # Ejercicio Thread04 - git init - git config --global user.name "Juanjo" diff --git a/navegadores/BrowserApp.py b/navegadores/BrowserApp.py new file mode 100644 index 0000000..8a6333e --- /dev/null +++ b/navegadores/BrowserApp.py @@ -0,0 +1,65 @@ +import sys +from PyQt5.QtCore import QUrl +from PyQt5.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QWidget, QLineEdit, QAction, QToolBar +from PyQt5.QtWebEngineWidgets import QWebEngineView + +class BrowserTab(QWebEngineView): + def __init__(self, url="https://google.com"): + super().__init__() + self.load(QUrl.fromUserInput(url)) # Convertir URL de str a QUrl + +class BrowserApp(QMainWindow): + def __init__(self): + super().__init__() + self.setWindowTitle("Navegador Web con PyQt5") + self.resize(1024, 768) + + # Barra de herramientas para la URL + self.toolbar = QToolBar() + self.addToolBar(self.toolbar) + + # Campo de entrada para la URL + self.url_bar = QLineEdit() + self.url_bar.returnPressed.connect(self.navigate_to_url) + self.toolbar.addWidget(self.url_bar) + + # Botón de nueva pestaña + new_tab_action = QAction("Nueva pestaña", self) + new_tab_action.triggered.connect(self.add_new_tab) + self.toolbar.addAction(new_tab_action) + + # Contenedor de pestañas + self.tabs = QTabWidget() + self.tabs.setDocumentMode(True) + self.tabs.tabCloseRequested.connect(self.close_current_tab) + self.setCentralWidget(self.tabs) + + # Añadir una primera pestaña + self.add_new_tab("https://google.com") + + def add_new_tab(self, url="https://google.com"): + new_tab = BrowserTab(url) + i = self.tabs.addTab(new_tab, "Nueva Pestaña") + self.tabs.setCurrentIndex(i) + new_tab.urlChanged.connect(self.update_url_bar) + self.url_bar.setText(url) + + def close_current_tab(self, index): + if self.tabs.count() > 1: + self.tabs.removeTab(index) + + def navigate_to_url(self): + url = self.url_bar.text() + if not url.startswith("http"): + url = "http://" + url + # Navegar usando QUrl + self.tabs.currentWidget().setUrl(QUrl.fromUserInput(url)) + + def update_url_bar(self, qurl): + self.url_bar.setText(qurl.toString()) + +if __name__ == "__main__": + app = QApplication(sys.argv) + browser = BrowserApp() + browser.show() + sys.exit(app.exec_()) diff --git a/navegadores/chrome.py b/navegadores/chrome.py new file mode 100644 index 0000000..19cdad2 --- /dev/null +++ b/navegadores/chrome.py @@ -0,0 +1,100 @@ +import tkinter as tk +from tkinter import ttk +from cefpython3 import cefpython as cef +import sys + +class BrowserTab: + def __init__(self, master, url="https://google.com"): + self.frame = tk.Frame(master) + self.frame.pack(fill=tk.BOTH, expand=True) + + # Inicializa la instancia de navegador CEF dentro del Frame + window_info = cef.WindowInfo() + window_info.SetAsChild(self.frame.winfo_id()) + self.browser = cef.CreateBrowserSync(window_info, url=url) + + def navigate(self, url): + # Navegar a una nueva URL + self.browser.LoadUrl(url) + + def close(self): + # Cerrar el navegador CEF en esta pestaña + self.browser.CloseBrowser() + +class BrowserApp(tk.Tk): + def __init__(self): + super().__init__() + + # Configuración de la ventana principal + self.title("Navegador Web con Tkinter y CEF") + self.geometry("1024x768") + + # Mantener una lista de pestañas (para el control de las instancias de navegador) + self.tabs = {} + + # Crear el contenedor de pestañas y la barra de URL + self.create_ui() + + # Inicializar CEF + cef.Initialize() + + def create_ui(self): + # Frame superior para la barra de URL y los botones + top_frame = tk.Frame(self, height=30) + top_frame.pack(fill=tk.X) + + # Botón para nueva pestaña + new_tab_btn = tk.Button(top_frame, text="Nueva Pestaña", command=self.new_tab) + new_tab_btn.pack(side=tk.LEFT, padx=5) + + # Campo de entrada para la URL + self.url_entry = tk.Entry(top_frame) + self.url_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5) + self.url_entry.bind("", self.load_url) # Ejecuta `load_url` al presionar Enter + + # Botón para cargar URL + go_btn = tk.Button(top_frame, text="Ir", command=self.load_url) + go_btn.pack(side=tk.LEFT, padx=5) + + # Crear el notebook para las pestañas + self.notebook = ttk.Notebook(self) + self.notebook.pack(fill=tk.BOTH, expand=True) + + # Agregar una pestaña inicial + self.new_tab() + + def new_tab(self): + # Crear un frame para una nueva pestaña + tab_id = len(self.tabs) + 1 + new_tab = BrowserTab(self.notebook) + self.tabs[tab_id] = new_tab + + # Agregar la pestaña al notebook con la página predeterminada de Google + self.notebook.add(new_tab.frame, text=f"Pestaña {tab_id}") + self.notebook.select(new_tab.frame) # Seleccionar la nueva pestaña + + def load_url(self, event=None): + # Cargar la URL en la pestaña seleccionada + url = self.url_entry.get() + if not url.startswith("http"): + url = "http://" + url # Asegura el prefijo "http://" + + # Obtener la pestaña seleccionada + selected_tab = self.notebook.select() + for tab_id, tab in self.tabs.items(): + if str(tab.frame) == selected_tab: + tab.navigate(url) + break + + def on_close(self): + # Cierra todas las instancias de navegador al cerrar la aplicación + for tab in self.tabs.values(): + tab.close() + cef.Shutdown() + self.destroy() + +# Crear y ejecutar la aplicación +if __name__ == "__main__": + app = BrowserApp() + app.protocol("WM_DELETE_WINDOW", app.on_close) # Cerrar adecuadamente la app y CEF + app.mainloop() diff --git a/navegadores/ejemplo1.py b/navegadores/ejemplo1.py new file mode 100644 index 0000000..e120051 --- /dev/null +++ b/navegadores/ejemplo1.py @@ -0,0 +1,99 @@ +import tkinter as tk +from tkinter import ttk +from tkhtmlview import HTMLLabel + +class Aplicacion(tk.Tk): + def __init__(self): + super().__init__() + + # Configuración de la ventana principal + self.title("Aplicación con Navegador en Tkinter") + self.geometry("800x600") + + # Creación del menú superior + self.crear_menu() + + # Creación del frame de contenido central con pestañas + self.crear_frame_central() + + # Creación de la barra de estado inferior + self.crear_barra_estado() + + def crear_menu(self): + # Barra de menú + menubar = tk.Menu(self) + + # Menú "Archivo" + archivo_menu = tk.Menu(menubar, tearoff=0) + archivo_menu.add_command(label="Nuevo") + archivo_menu.add_command(label="Abrir") + archivo_menu.add_command(label="Guardar") + archivo_menu.add_separator() + archivo_menu.add_command(label="Salir", command=self.quit) + menubar.add_cascade(label="Archivo", menu=archivo_menu) + + # Menú "Editar" + editar_menu = tk.Menu(menubar, tearoff=0) + editar_menu.add_command(label="Deshacer") + editar_menu.add_command(label="Rehacer") + menubar.add_cascade(label="Editar", menu=editar_menu) + + # Menú "Ayuda" + ayuda_menu = tk.Menu(menubar, tearoff=0) + ayuda_menu.add_command(label="Acerca de") + menubar.add_cascade(label="Ayuda", menu=ayuda_menu) + + # Asignar el menú a la ventana + self.config(menu=menubar) + + def crear_frame_central(self): + # Frame central con pestañas + frame_central = ttk.Frame(self) + frame_central.pack(fill="both", expand=True, padx=10, pady=10) + + # Notebook para las pestañas + notebook = ttk.Notebook(frame_central) + notebook.pack(fill="both", expand=True) + + # Crear cuatro solapas normales + for i in range(1, 5): + tab = ttk.Frame(notebook) + notebook.add(tab, text=f"Solapa {i}") + # Añadir un Label en cada solapa para diferenciarla + label = ttk.Label(tab, text=f"Contenido de la Solapa {i}") + label.pack(pady=10) + + # Crear la solapa del navegador + navegador_tab = ttk.Frame(notebook) + notebook.add(navegador_tab, text="Navegador") + + # Crear un visor HTML en la solapa del navegador + html_content = """ +

Bienvenido al Navegador Embebido

+

Este es un ejemplo de un navegador simple embebido en Tkinter usando tkhtmlview.

+

Puedes cargar contenido HTML aquí, incluyendo enlaces y estilos básicos.

+ """ + + navegador = HTMLLabel(navegador_tab, html=html_content) + navegador.pack(fill="both", expand=True, padx=20, pady=20) + + def crear_barra_estado(self): + # Barra de estado inferior con tres secciones + barra_estado = ttk.Frame(self, relief="sunken") + barra_estado.pack(side="bottom", fill="x") + + # Crear tres secciones en la barra de estado + seccion_izquierda = ttk.Label(barra_estado, text="Sección 1") + seccion_izquierda.pack(side="left", padx=10) + + seccion_centro = ttk.Label(barra_estado, text="Sección 2") + seccion_centro.pack(side="left", padx=10) + + seccion_derecha = ttk.Label(barra_estado, text="Sección 3") + seccion_derecha.pack(side="right", padx=10) + +# Crear y ejecutar la aplicación +if __name__ == "__main__": + app = Aplicacion() + app.mainloop() +