Web 浏览器范例 (ActiveQt)

The code demonstrates how the Qt application can communicate with the embedded ActiveX controls using signals, slots and the dynamicCall() function.

class MainWindow : public QMainWindow, public Ui::MainWindow
{
    Q_OBJECT
public:
    explicit MainWindow();
    virtual ~MainWindow();
public slots:
    void navigate(const QString &address);
    void on_WebBrowser_TitleChange(const QString &title);
    void on_WebBrowser_ProgressChange(int a, int b);
    void on_WebBrowser_CommandStateChange(int cmd, bool on);
    void on_WebBrowser_BeforeNavigate();
    void on_WebBrowser_NavigateComplete(const QString &address);
    void on_actionGo_triggered();
    void on_actionNewWindow_triggered();
    void on_actionAddBookmark_triggered();
    void on_actionAbout_triggered();
    void on_actionAboutQt_triggered();
    void on_actionFileClose_triggered();
private:
    inline const QString address() const
        { return m_addressEdit->text().trimmed(); }
    QList<Location> bookmarks() const;
    QAction *addLocation(const Location &location, QMenu *menu);
    inline void addBookmark(const Location &location)
        { m_bookmarkActions << addLocation(location, BookmarksMenu); }
    QProgressBar *m_progressBar;
    QLineEdit *m_addressEdit;
    QList<QAction *> m_bookmarkActions;
    QList<QAction *> m_historyActions;
    QSignalMapper m_locationActionMapper;
};
					

The MainWindow 类声明 QMainWindow 基用户界面,使用 Ui::MainWindow class generated by Qt Designer. A number of slots are implemented to handle events from the various user interface elements, including the WebBrowser object, which is a QAxWidget hosting the Microsoft Web Browser control.

MainWindow::MainWindow()
{
    setupUi(this);
    m_addressEdit = new QLineEdit;
    tbAddress->insertWidget(actionGo, new QLabel(tr("Address")));
    tbAddress->insertWidget(actionGo, m_addressEdit);
    connect(m_addressEdit, SIGNAL(returnPressed()), actionGo, SLOT(trigger()));
    connect(actionBack, SIGNAL(triggered()), WebBrowser, SLOT(GoBack()));
    connect(actionForward, SIGNAL(triggered()), WebBrowser, SLOT(GoForward()));
    connect(actionStop, SIGNAL(triggered()), WebBrowser, SLOT(Stop()));
    connect(actionRefresh, SIGNAL(triggered()), WebBrowser, SLOT(Refresh()));
    connect(actionHome, SIGNAL(triggered()), WebBrowser, SLOT(GoHome()));
    connect(actionSearch, SIGNAL(triggered()), WebBrowser, SLOT(GoSearch()));
    m_progressBar = new QProgressBar(statusBar());
    m_progressBar->setTextVisible(false);
    m_progressBar->hide();
    statusBar()->addPermanentWidget(m_progressBar);
    connect(&m_locationActionMapper, QOverload<const QString &>::of(&QSignalMapper::mapped), this, &MainWindow::navigate);
    QSettings settings(QSettings::IniFormat, QSettings::UserScope,
                       QCoreApplication::organizationName(), QCoreApplication::applicationName());
    const QByteArray restoredGeometry = settings.value(QLatin1String(geometryKey)).toByteArray();
    if (restoredGeometry.isEmpty() || !restoreGeometry(restoredGeometry)) {
        const QRect availableGeometry = QApplication::desktop()->availableGeometry(this);
        const QSize size = (availableGeometry.size() * 4) / 5;
        resize(size);
        move(availableGeometry.center() - QPoint(size.width(), size.height()) / 2);
    }
    const QString restoredVersion = settings.value(QLatin1String(versionKey)).toString();
    QList<Location> bookmarks = readBookMarks(settings);
    if (bookmarks.isEmpty() || restoredVersion.isEmpty())
        bookmarks = defaultBookmarks();
    for (const Location &bookmark : qAsConst(bookmarks))
        addBookmark(bookmark);
}
					

The constructor initializes the user interface, installs a progress bar on the status bar, and loads the bookmarks.

void MainWindow::on_WebBrowser_TitleChange(const QString &title)
{
    // This is called multiple times after NavigateComplete().
    // Add new URLs to history here.
    setWindowTitle(tr("Qt WebBrowser - ") + title);
    const QString currentAddress = address();
    const QString historyAddress = m_historyActions.isEmpty() ?
        QString() : locationFromAction(m_historyActions.last()).address;
    if (currentAddress.isEmpty() || currentAddress == QStringLiteral("about:blank") || currentAddress == historyAddress)
        return;
    m_historyActions << addLocation(Location(title, currentAddress), HistoryMenu);
    if (m_historyActions.size() > 10)
        delete m_historyActions.takeFirst();
}
void MainWindow::on_WebBrowser_ProgressChange(int a, int b)
{
    if (a <= 0 || b <= 0) {
        m_progressBar->hide();
        return;
    }
    m_progressBar->setRange(0, b);
    m_progressBar->setValue(a);
    m_progressBar->show();
}
void MainWindow::on_WebBrowser_CommandStateChange(int cmd, bool on)
{
    switch (cmd) {
    case 1:
        actionForward->setEnabled(on);
        break;
    case 2:
        actionBack->setEnabled(on);
        break;
    }
}
void MainWindow::on_WebBrowser_BeforeNavigate()
{
    actionStop->setEnabled(true);
}
void MainWindow::on_WebBrowser_NavigateComplete(const QString &url)
{
    QSignalBlocker blocker(m_addressEdit);
    actionStop->setEnabled(false);
    m_addressEdit->setText(url);
}
void MainWindow::on_actionGo_triggered()
{
    navigate(address());
}
					

Different slots handle the signals emitted by the WebBrowser object.

Connections that don't require any coding, i.e. connecting the back action to the GoBack() slot, have already been made in Qt Designer.

void MainWindow::on_actionGo_triggered()
{
    navigate(address());
}
void MainWindow::navigate(const QString &url)
{
    WebBrowser->dynamicCall("Navigate(const QString&)", url);
}
void MainWindow::on_actionNewWindow_triggered()
{
    MainWindow *window = new MainWindow;
    window->show();
    if (m_addressEdit->text().isEmpty())
        return;
    window->m_addressEdit->setText(m_addressEdit->text());
    window->actionStop->setEnabled(true);
    window->on_actionGo_triggered();
}
void MainWindow::on_actionAbout_triggered()
{
    QMessageBox::about(this, tr("About WebBrowser"),
                       tr("This Example has been created using the ActiveQt integration into Qt Designer.\n"
                       "It demonstrates the use of QAxWidget to embed the Internet Explorer ActiveX\n"
                       "control into a Qt application."));
}
void MainWindow::on_actionAboutQt_triggered()
{
    QMessageBox::aboutQt(this, tr("About Qt"));
}
void MainWindow::on_actionFileClose_triggered()
{
    close();
}
#include "main.moc"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCoreApplication::setApplicationVersion(QT_VERSION_STR);
    QCoreApplication::setApplicationName(QStringLiteral("Active Qt Web Browser"));
    QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
    MainWindow w;
    const auto &arguments = QCoreApplication::arguments();
    const QString url = arguments.value(1, QString::fromLatin1(qtUrl));
    w.navigate(url);
    w.show();
    return a.exec();
}
					

The rest of the implementation is not related to ActiveQt - the actions are handled by different slots, and the entry point function starts the application using standard Qt APIs.

要构建范例必须先构建 QAxContainer 库。然后运行 make 工具在 examples/activeqt/webbrowser 和运行结果 webbrowser.exe .

文件: