|
3 | 3 | from PyQt5.QtWidgets import *
|
4 | 4 | from PyQt5.QtWebEngineWidgets import *
|
5 | 5 |
|
| 6 | +class BrowserTab(QWebEngineView): |
| 7 | + def __init__(self, parent=None): |
| 8 | + super().__init__(parent) |
| 9 | + self.load(QUrl("https://www.google.com")) # Página inicial padrão para cada nova guia |
| 10 | + |
6 | 11 | class MiniNavegador(QMainWindow):
|
7 | 12 | def __init__(self):
|
8 | 13 | super().__init__()
|
9 | 14 |
|
10 |
| - # Inicializa o navegador |
11 |
| - self.browser = QWebEngineView() |
| 15 | + self.setWindowTitle("Navegador Py-Tech") # Novo título |
| 16 | + self.resize(1200, 800) # Aumenta o tamanho da janela |
| 17 | + |
| 18 | + # Barra de navegação (Toolbar) |
| 19 | + self.toolbar = QToolBar("Navegação") |
| 20 | + self.addToolBar(self.toolbar) |
| 21 | + |
| 22 | + # Botões da barra de navegação |
| 23 | + back_btn = QAction("⬅️ Voltar", self) |
| 24 | + back_btn.setStatusTip("Voltar para a página anterior") |
| 25 | + back_btn.triggered.connect(self.current_browser().back) |
| 26 | + self.toolbar.addAction(back_btn) |
| 27 | + |
| 28 | + forward_btn = QAction("➡️ Avançar", self) |
| 29 | + forward_btn.setStatusTip("Avançar para a próxima página") |
| 30 | + forward_btn.triggered.connect(self.current_browser().forward) |
| 31 | + self.toolbar.addAction(forward_btn) |
12 | 32 |
|
13 |
| - # Definindo a página inicial |
14 |
| - self.browser.setUrl(QUrl("http://www.google.com")) |
| 33 | + reload_btn = QAction("🔄 Recarregar", self) |
| 34 | + reload_btn.setStatusTip("Recarregar a página atual") |
| 35 | + reload_btn.triggered.connect(self.current_browser().reload) |
| 36 | + self.toolbar.addAction(reload_btn) |
15 | 37 |
|
16 |
| - # Barra de navegação |
17 |
| - self.url_bar = QLineEdit(self) |
| 38 | + home_btn = QAction("🏠 Início", self) |
| 39 | + home_btn.setStatusTip("Ir para a página inicial") |
| 40 | + home_btn.triggered.connect(self.navigate_home) |
| 41 | + self.toolbar.addAction(home_btn) |
| 42 | + |
| 43 | + self.url_bar = QLineEdit() |
18 | 44 | self.url_bar.returnPressed.connect(self.navigate_to_url)
|
| 45 | + self.toolbar.addWidget(self.url_bar) |
19 | 46 |
|
20 |
| - # Botões de navegação |
21 |
| - self.back_button = QPushButton("Voltar", self) |
22 |
| - self.forward_button = QPushButton("Avançar", self) |
23 |
| - self.refresh_button = QPushButton("Atualizar", self) |
| 47 | + # Botão para adicionar nova guia |
| 48 | + new_tab_btn = QAction("➕ Nova Guia", self) |
| 49 | + new_tab_btn.setStatusTip("Abrir uma nova guia") |
| 50 | + new_tab_btn.triggered.connect(self.add_new_tab) |
| 51 | + self.toolbar.addAction(new_tab_btn) |
24 | 52 |
|
25 |
| - # Conectar os botões às funções |
26 |
| - self.back_button.clicked.connect(self.go_back) |
27 |
| - self.forward_button.clicked.connect(self.go_forward) |
28 |
| - self.refresh_button.clicked.connect(self.refresh_page) |
| 53 | + # --- Suporte a Guias --- |
| 54 | + self.tabs = QTabWidget() |
| 55 | + self.tabs.setDocumentMode(True) # Modo de documento (aparência mais moderna) |
| 56 | + self.tabs.tabBarDoubleClicked.connect(self.tab_open_doubleclick) # Abrir nova aba ao clicar duas vezes |
| 57 | + self.tabs.currentChanged.connect(self.current_tab_changed) # Mudar URL na barra quando a aba muda |
29 | 58 |
|
30 |
| - # Layout dos botões |
31 |
| - button_layout = QHBoxLayout() |
32 |
| - button_layout.addWidget(self.back_button) |
33 |
| - button_layout.addWidget(self.forward_button) |
34 |
| - button_layout.addWidget(self.refresh_button) |
| 59 | + self.setCentralWidget(self.tabs) |
35 | 60 |
|
36 |
| - # Layout principal |
37 |
| - layout = QVBoxLayout() |
38 |
| - layout.addLayout(button_layout) |
39 |
| - layout.addWidget(self.url_bar) |
40 |
| - layout.addWidget(self.browser) |
| 61 | + self.add_new_tab(QUrl("https://www.google.com"), "Página Inicial") # Adiciona a primeira guia |
41 | 62 |
|
42 |
| - # Configuração do widget central |
43 |
| - container = QWidget() |
44 |
| - container.setLayout(layout) |
45 |
| - self.setCentralWidget(container) |
| 63 | + # Ocultar a barra de status por enquanto (pode ser adicionada depois se necessário) |
| 64 | + self.statusBar().hide() |
46 | 65 |
|
47 |
| - # Ajusta o tamanho da janela |
48 |
| - self.setWindowTitle("Mini Navegador") |
49 |
| - self.resize(1024, 768) |
| 66 | + def current_browser(self): |
| 67 | + """Retorna a instância do navegador da guia atual.""" |
| 68 | + return self.tabs.currentWidget() |
50 | 69 |
|
51 |
| - # Conectar barra de URL à mudança de página |
52 |
| - self.browser.urlChanged.connect(self.update_url) |
| 70 | + def add_new_tab(self, qurl=None, label="Nova Guia"): |
| 71 | + """Adiciona uma nova guia ao navegador.""" |
| 72 | + if qurl is None: |
| 73 | + qurl = QUrl("https://www.google.com") # Padrão para nova aba |
53 | 74 |
|
54 |
| - def navigate_to_url(self): |
55 |
| - url = self.url_bar.text() |
56 |
| - self.browser.setUrl(QUrl(url)) |
| 75 | + browser = BrowserTab() |
| 76 | + browser.setUrl(qurl) |
57 | 77 |
|
58 |
| - def update_url(self, q): |
59 |
| - self.url_bar.setText(q.toString()) |
| 78 | + i = self.tabs.addTab(browser, label) |
| 79 | + self.tabs.setCurrentIndex(i) |
60 | 80 |
|
61 |
| - def go_back(self): |
62 |
| - """Voltar para a página anterior.""" |
63 |
| - if self.browser.canGoBack(): |
64 |
| - self.browser.back() |
| 81 | + # Atualiza a URL na barra quando a página muda |
| 82 | + browser.urlChanged.connect(lambda qurl, browser=browser: self.update_urlbar(qurl, browser)) |
| 83 | + browser.loadStarted.connect(lambda: self.update_buttons_state()) # Atualiza estado dos botões |
| 84 | + browser.loadFinished.connect(lambda success: self.update_buttons_state()) # Atualiza estado dos botões |
65 | 85 |
|
66 |
| - def go_forward(self): |
67 |
| - """Avançar para a próxima página.""" |
68 |
| - if self.browser.canGoForward(): |
69 |
| - self.browser.forward() |
| 86 | + def tab_open_doubleclick(self, index): |
| 87 | + """Abre uma nova guia ao dar clique duplo na barra de abas.""" |
| 88 | + if index == -1: # Clicou em uma área vazia |
| 89 | + self.add_new_tab() |
70 | 90 |
|
71 |
| - def refresh_page(self): |
72 |
| - """Atualizar a página atual.""" |
73 |
| - self.browser.reload() |
| 91 | + def current_tab_changed(self, index): |
| 92 | + """Atualiza a barra de URL quando a guia ativa muda.""" |
| 93 | + qurl = self.current_browser().url() |
| 94 | + self.update_urlbar(qurl, self.current_browser()) |
| 95 | + self.update_buttons_state() # Garante que os botões refletem a guia atual |
| 96 | + |
| 97 | + def navigate_home(self): |
| 98 | + """Volta para a página inicial.""" |
| 99 | + self.current_browser().setUrl(QUrl("https://www.google.com")) |
| 100 | + |
| 101 | + def navigate_to_url(self): |
| 102 | + """ |
| 103 | + Navega para a URL digitada, adiciona HTTPS por padrão |
| 104 | + ou faz uma pesquisa no Google. |
| 105 | + """ |
| 106 | + url = self.url_bar.text() |
| 107 | + |
| 108 | + # 1. Adiciona https:// se não houver protocolo |
| 109 | + if not url.startswith("http://") and not url.startswith("https://"): |
| 110 | + # Verifica se parece um domínio (contém pelo menos um ponto) |
| 111 | + if "." in url and not " " in url: |
| 112 | + url = "https://" + url # Tenta HTTPS por padrão |
| 113 | + else: |
| 114 | + # 2. Se não parecer uma URL, faz uma pesquisa no Google |
| 115 | + search_query = QUrl.toPercentEncoding(url) |
| 116 | + url = f"https://www.google.com/search?q={search_query}" |
| 117 | + |
| 118 | + self.current_browser().setUrl(QUrl(url)) |
| 119 | + self.update_buttons_state() # Atualiza o estado dos botões após a navegação |
| 120 | + |
| 121 | + def update_urlbar(self, q, browser=None): |
| 122 | + """Atualiza a barra de URL com a URL da guia atual.""" |
| 123 | + if browser != self.current_browser(): |
| 124 | + # Impede que URLs de guias em segundo plano atualizem a barra principal |
| 125 | + return |
| 126 | + |
| 127 | + self.url_bar.setText(q.toString()) |
| 128 | + self.url_bar.setCursorPosition(0) # Volta o cursor para o início |
| 129 | + |
| 130 | + def update_buttons_state(self): |
| 131 | + """Atualiza o estado (habilitado/desabilitado) dos botões de navegação.""" |
| 132 | + browser = self.current_browser() |
| 133 | + if browser: |
| 134 | + # Encontra as ações na toolbar para atualizá-las |
| 135 | + for action in self.toolbar.actions(): |
| 136 | + if action.text() == "⬅️ Voltar": |
| 137 | + action.setEnabled(browser.url() != QUrl("https://www.google.com") and browser.canGoBack()) |
| 138 | + elif action.text() == "➡️ Avançar": |
| 139 | + action.setEnabled(browser.canGoForward()) |
| 140 | + else: |
| 141 | + # Desabilita todos os botões se não houver navegador ativo |
| 142 | + for action in self.toolbar.actions(): |
| 143 | + action.setEnabled(False) |
74 | 144 |
|
75 | 145 | # Função principal para rodar o aplicativo
|
76 | 146 | if __name__ == "__main__":
|
77 | 147 | app = QApplication(sys.argv)
|
| 148 | + QApplication.setApplicationName("Navegador Py-Tech") # Define o nome da aplicação para o sistema |
78 | 149 | navegador = MiniNavegador()
|
79 | 150 | navegador.show()
|
80 | 151 | sys.exit(app.exec_())
|
0 commit comments