Webview em QML (Qt Modeling Language)
Tags: qml, webview, website, qt
Published: 2024-06-26 22:06:05

## Introdução
O código a seguir é um exemplo de uma aplicação básica em QML (Qt Modeling Language) que cria uma janela de aplicação que incorpora um visualizador de web (WebEngineView) para exibir a página do Google. Ele inclui funcionalidades como um menu de contexto, ícone de bandeja do sistema (SystemTrayIcon), e um histórico de URLs visitadas. A aplicação também possui vários itens de menu para interações adicionais, como copiar, colar, cortar, selecionar tudo, atualizar, zoom in, zoom out, e abrir o URL em um navegador externo. Vamos as explicação do código

### Código completo

```
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtWebEngine 1.10
import Qt.labs.platform 1.1

ApplicationWindow {
    id: window
    visible: true
    width: 1024
    height: 768
    title: "Google"

    WebEngineView {
        id: webEngineView
        anchors.fill: parent
        url: "https://www.google.com"

        onUrlChanged: {
            historyModel.append({url: webEngineView.url.toString()})
        }
    }

    ListModel {
        id: historyModel
    }

    ListView {
        id: historyView
        width: parent.width
        height: 200
        model: historyModel
        delegate: Text {
            text: url
        }
        visible: false // Defina como true para visualizar o histórico
    }

    MouseArea {
        anchors.fill: parent
        acceptedButtons: Qt.RightButton
        onPressed: {
            if (mouse.button == Qt.RightButton) {
                contextMenu.open(mouse.x, mouse.y)
            }
        }
    }

    Menu {
        id: contextMenu
        MenuItem {
            text: qsTr("Copy")
            onTriggered: webEngineView.triggerWebAction(WebEngineView.Copy)
        }
        MenuItem {
            text: qsTr("Paste")
            onTriggered: webEngineView.triggerWebAction(WebEngineView.Paste)
        }
        MenuItem {
            text: qsTr("Cut")
            onTriggered: webEngineView.triggerWebAction(WebEngineView.Cut)
        }
        MenuItem {
            text: qsTr("Select All")
            onTriggered: webEngineView.triggerWebAction(WebEngineView.SelectAll)
        }
        MenuItem {
            text: qsTr("Refresh")
            onTriggered: webEngineView.triggerWebAction(WebEngineView.Reload)
        }
        MenuItem {
            text: qsTr("Zoom In")
            onTriggered: { webEngineView.zoomFactor += 0.1; }
        }
        MenuItem {
            text: qsTr("Zoom Out")
            onTriggered: { webEngineView.zoomFactor -= 0.1; }
        }
        MenuItem {
            text: qsTr("Open in external browser")
            onTriggered: {
                Qt.openUrlExternally(webEngineView.url)
            }
        }
    }

 SystemTrayIcon {
    id: trayIcon
    visible: true
    icon.source: "./imagens/google.png" // No caso a pasta onde está a imagem do ícone

    menu: Menu {
        MenuItem {
            text: "Open"
            onTriggered: {
                window.show()
                window.raise()
                window.requestActivate()
            }
        }
        MenuItem {
            text: "Open Specific URL"
            onTriggered: {
                webEngineView.url = "http://www.google.com"
                window.show()
                window.raise()
                window.requestActivate()
            }
        }
        MenuItem {
            text: "Toggle History View"
            onTriggered: {
                historyView.visible = !historyView.visible
            }
        }
        MenuItem {
            text: "Settings"
            onTriggered: {
                // Implemente a lógica para abrir a janela de configurações
            }
        }
        MenuItem {
            text: "Exit"
            onTriggered: Qt.quit()
        }
    }

    onActivated: reason => {
        if (reason === SystemTrayIcon.Trigger) {
            if (window.visible) {
                window.hide()
            } else {
                window.show()
                window.raise()
                window.requestActivate()
            }
        }
    }
}

onClosing: {
    close.accepted = false;
    window.hide();
}

Component.onCompleted: {
    trayIcon.show()
}

}
```

### Explicação do Código



```
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import QtWebEngine 1.10
import Qt.labs.platform 1.1
```

Esses comandos importam os módulos necessários para a aplicação. QtQuick é usado para interfaces de usuário, QtQuick.Controls para controles padrão (como botões e menus), QtQuick.Layouts para layouts, QtWebEngine para exibir páginas web, e Qt.labs.platform para acessar funcionalidades específicas da plataforma.

---
```
ApplicationWindow {
    id: window
    visible: true
    width: 1024
    height: 768
    title: "Google"
```

`ApplicationWindow` define a janela principal da aplicação, com uma largura de 1024 pixels, altura de 768 pixels, e o título "Google".

---
```
WebEngineView {
    id: webEngineView
    anchors.fill: parent
    url: "https://www.google.com"

    onUrlChanged: {
        historyModel.append({url: webEngineView.url.toString()})
    }
}
```

`WebEngineView` é o componente que carrega e exibe a página web. Quando o URL muda, a nova URL é adicionada ao modelo de histórico (`historyModel`).

---

```
ListModel {
    id: historyModel
}

ListView {
    id: historyView
    width: parent.width
    height: 200
    model: historyModel
    delegate: Text {
        text: url
    }
    visible: false // Defina como true para visualizar o histórico
}
```

`ListModel` armazena as URLs visitadas. `ListView` exibe esse histórico, mas está inicialmente invisível (`visible: false`).

---

```
MouseArea {
    anchors.fill: parent
    acceptedButtons: Qt.RightButton
    onPressed: {
        if (mouse.button == Qt.RightButton) {
            contextMenu.open(mouse.x, mouse.y)
        }
    }
}
```

`MouseArea` detecta cliques do mouse. Se o botão direito do mouse for pressionado, o menu de contexto (`contextMenu`) é aberto na posição do clique.

---

```
Menu {
    id: contextMenu
    MenuItem {
        text: qsTr("Copy")
        onTriggered: webEngineView.triggerWebAction(WebEngineView.Copy)
    }
    MenuItem {
        text: qsTr("Paste")
        onTriggered: webEngineView.triggerWebAction(WebEngineView.Paste)
    }
    MenuItem {
        text: qsTr("Cut")
        onTriggered: webEngineView.triggerWebAction(WebEngineView.Cut)
    }
    MenuItem {
        text: qsTr("Select All")
        onTriggered: webEngineView.triggerWebAction(WebEngineView.SelectAll)
    }
    MenuItem {
        text: qsTr("Refresh")
        onTriggered: webEngineView.triggerWebAction(WebEngineView.Reload)
    }
    MenuItem {
        text: qsTr("Zoom In")
        onTriggered: { webEngineView.zoomFactor += 0.1; }
    }
    MenuItem {
        text: qsTr("Zoom Out")
        onTriggered: { webEngineView.zoomFactor -= 0.1; }
    }
    MenuItem {
        text: qsTr("Open in external browser")
        onTriggered: {
            Qt.openUrlExternally(webEngineView.url)
        }
    }
}
```

`Menu` define um menu de contexto com várias opções, como copiar, colar, cortar, selecionar tudo, atualizar, zoom in, zoom out, e abrir o URL em um navegador externo.

---

```
SystemTrayIcon {
    id: trayIcon
    visible: true
    icon.source: "./imagens/google.png" // No caso a pasta onde está a imagem do ícone

    menu: Menu {
        MenuItem {
            text: "Open"
            onTriggered: {
                window.show()
                window.raise()
                window.requestActivate()
            }
        }
        MenuItem {
            text: "Open Specific URL"
            onTriggered: {
                webEngineView.url = "http://www.google.com"
                window.show()
                window.raise()
                window.requestActivate()
            }
        }
        MenuItem {
            text: "Toggle History View"
            onTriggered: {
                historyView.visible = !historyView.visible
            }
        }
        MenuItem {
            text: "Settings"
            onTriggered: {
                // Implemente a lógica para abrir a janela de configurações
            }
        }
        MenuItem {
            text: "Exit"
            onTriggered: Qt.quit()
        }
    }

    onActivated: reason => {
        if (reason === SystemTrayIcon.Trigger) {
            if (window.visible) {
                window.hide()
            } else {
                window.show()
                window.raise()
                window.requestActivate()
            }
        }
    }
}
```

`SystemTrayIcon` cria um ícone na bandeja do sistema com um menu. As opções do menu permitem abrir a aplicação, abrir um URL específico, alternar a visualização do histórico, abrir configurações e sair da aplicação. A aplicação pode ser minimizada para a bandeja do sistema e restaurada a partir dela.

---

```
onClosing: {
    close.accepted = false;
    window.hide();
}

Component.onCompleted: {
    trayIcon.show()
}
```

Esses manipuladores de evento garantem que a aplicação não seja completamente fechada ao clicar em fechar, mas sim escondida. `Component.onCompleted` exibe o ícone na bandeja quando a aplicação é iniciada.

---
### Conclusão

O código exemplifica uma aplicação QML que utiliza `WebEngineView` para carregar o Google, inclui um menu de contexto para várias operações, e um ícone de bandeja do sistema para facilitar o acesso e controle da aplicação. Os elementos chave como `MouseArea` e `SystemTrayIcon` melhoram a usabilidade, permitindo que os usuários interajam com a aplicação de maneira intuitiva e eficiente. Este exemplo é uma boa base para criar aplicativos web integrados com funcionalidades de interface de usuário ricas e interativas.