Exemple Qutlook (ActiveQt)
L'exemple Qutlook démontre l'utilisation d'ActiveQt pour automatiser Outlook. L'exemple utilise l'outil dumpcpp pour générer un espace de noms C++ pour la bibliothèque de types décrivant le modèle d'objets Outlook.
Le fichier de projet de l'exemple ressemble à ceci :
TEMPLATE = app
TARGET = qutlook
QT += widgets axcontainer
TYPELIBS = $$system(dumpcpp -getfile {00062FFF-0000-0000-C000-000000000046})
isEmpty(TYPELIBS) {
message("Microsoft Outlook type library not found!")
REQUIRES += Outlook
} else {
HEADERS = addressview.h
SOURCES = addressview.cpp main.cpp
}Le fichier de projet utilise l'outil dumpcpp pour ajouter une bibliothèque de types MS Outlook au projet. En cas d'échec, le makefile généré affichera simplement un message d'erreur, sinon l'étape de construction exécutera l'outil dumpcpp sur la bibliothèque de types et générera un fichier d'en-tête et un fichier cpp (dans ce cas, msoutl.h et msoutl.cpp) qui déclarent et mettent en œuvre une API facile à utiliser pour les objets Outlook.
class AddressView : public QWidget { Q_OBJECT public: explicit AddressView(QWidget *parent = nullptr); protected slots: void addEntry(); void changeEntry(); void itemSelected(const QModelIndex &index); void updateOutlook(); protected: AddressBookModel *model; QTreeView *m_treeView; QPushButton *m_addButton; QPushButton *m_changeButton; QLineEdit *m_firstName; QLineEdit *m_lastName; QLineEdit *m_address; QLineEdit *m_email; };
La classe AddressView est une sous-classe de QWidget pour l'interface utilisateur. Le widget QTreeView affichera le contenu du dossier Contact d'Outlook tel qu'il est fourni par la classe model.
#include "addressview.h" #include "msoutl.h" #include <QtWidgets> class AddressBookModel : public QAbstractListModel { public: explicit AddressBookModel(AddressView *parent); virtual ~AddressBookModel(); int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QVariant data(const QModelIndex &index, int role) const; void changeItem(const QModelIndex &index, const QString &firstName, const QString &lastName, const QString &address, const QString &email); void addItem(const QString &firstName, const QString &lastName, const QString &address, const QString &email); void update(); private: Outlook::Application outlook; Outlook::Items *folderItems = nullptr; mutable QHash<QModelIndex, QStringList> cache; };
La classe AddressBookModel est une sous-classe de QAbstractListModel qui communique directement avec Outlook, en utilisant QHash pour la mise en cache.
AddressBookModel::AddressBookModel(AddressView *parent) : QAbstractListModel(parent) { if (!outlook.isNull()) { Outlook::NameSpace session(outlook.Session()); session.Logon(); Outlook::MAPIFolder *folder = session.GetDefaultFolder(Outlook::olFolderContacts); folderItems = new Outlook::Items(folder->Items()); connect(folderItems, SIGNAL(ItemAdd(IDispatch*)), parent, SLOT(updateOutlook())); connect(folderItems, SIGNAL(ItemChange(IDispatch*)), parent, SLOT(updateOutlook())); connect(folderItems, SIGNAL(ItemRemove()), parent, SLOT(updateOutlook())); delete folder; } }
Le constructeur initialise Outlook. Les différents signaux fournis par Outlook pour notifier les changements de contenu sont connectés à l'emplacement updateOutlook().
AddressBookModel::~AddressBookModel() { delete folderItems; if (!outlook.isNull()) Outlook::NameSpace(outlook.Session()).Logoff(); }
Le destructeur met fin à la session.
int AddressBookModel::rowCount(const QModelIndex &) const { return folderItems ? folderItems->Count() : 0; } int AddressBookModel::columnCount(const QModelIndex & /*parent*/) const { return 4; }
L'implémentation rowCount() renvoie le nombre d'entrées indiqué par Outlook. columnCount et headerData sont implémentés pour afficher quatre colonnes dans l'arborescence.
QVariant AddressBookModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const { if (role != Qt::DisplayRole) return QVariant(); switch (section) { case 0: return tr("First Name"); case 1: return tr("Last Name"); case 2: return tr("Address"); case 3: return tr("Email"); default: break; } return QVariant(); }
L'implémentation headerData() renvoie des chaînes codées en dur.
QVariant AddressBookModel::data(const QModelIndex &index, int role) const { if (!index.isValid() || role != Qt::DisplayRole) return QVariant(); QStringList data; if (cache.contains(index)) { data = cache.value(index); } else { Outlook::ContactItem contact(folderItems->Item(index.row() + 1)); if (contact.Class() == Outlook::OlObjectClass::olContact) data << contact.FirstName() << contact.LastName() << contact.HomeAddress() << contact.Email1Address(); cache.insert(index, data); } if (index.column() < data.size()) return data.at(index.column()); return QVariant(); }
L'implémentation data() est le cœur du modèle. Si les données demandées se trouvent dans le cache, la valeur du cache est utilisée, sinon les données sont obtenues auprès d'Outlook.
void AddressBookModel::changeItem(const QModelIndex &index, const QString &firstName, const QString &lastName, const QString &address, const QString &email) { Outlook::ContactItem item(folderItems->Item(index.row() + 1)); if (item.Class() != Outlook::OlObjectClass::olContact) return; // Not a contact item.SetFirstName(firstName); item.SetLastName(lastName); item.SetHomeAddress(address); item.SetEmail1Address(email); item.Save(); cache.take(index); }
Le slot changeItem() est appelé lorsque l'utilisateur modifie l'entrée courante à l'aide de l'interface utilisateur. L'élément Outlook est accessible à l'aide de l'API Outlook et est modifié à l'aide des paramètres de propriété. Enfin, l'élément est enregistré dans Outlook et supprimé du cache. Notez que le modèle ne signale pas la modification des données à la vue, car Outlook émettra un signal de son propre chef.
void AddressBookModel::addItem(const QString &firstName, const QString &lastName, const QString &address, const QString &email) { Outlook::ContactItem item(outlook.CreateItem(Outlook::olContactItem)); if (!item.isNull()) { item.SetFirstName(firstName); item.SetLastName(lastName); item.SetHomeAddress(address); item.SetEmail1Address(email); item.Save(); } }
Le slot addItem() appelle la méthode CreateItem d'Outlook pour créer un nouvel élément de contact, définit les propriétés du nouvel élément en fonction des valeurs saisies par l'utilisateur et enregistre l'élément.
void AddressBookModel::update() { beginResetModel(); cache.clear(); endResetModel(); }
Le slot update() efface le cache et émet le signal reset() pour notifier à la vue la modification des données nécessitant un nouveau dessin du contenu.
AddressView::AddressView(QWidget *parent) : QWidget(parent) { QGridLayout *mainGrid = new QGridLayout(this); QLabel *firstNameLabel = new QLabel(tr("First &Name"), this); firstNameLabel->resize(firstNameLabel->sizeHint()); mainGrid->addWidget(firstNameLabel, 0, 0); QLabel *lastNameLabel = new QLabel(tr("&Last Name"), this); lastNameLabel->resize(lastNameLabel->sizeHint()); mainGrid->addWidget(lastNameLabel, 0, 1); QLabel *addressLabel = new QLabel(tr("Add&ress"), this); addressLabel->resize(addressLabel->sizeHint()); mainGrid->addWidget(addressLabel, 0, 2); QLabel *emailLabel = new QLabel(tr("&E-Mail"), this); emailLabel->resize(emailLabel->sizeHint()); mainGrid->addWidget(emailLabel, 0, 3); m_addButton = new QPushButton(tr("A&dd"), this); m_addButton->resize(m_addButton->sizeHint()); mainGrid->addWidget(m_addButton, 0, 4); connect(m_addButton, &QPushButton::clicked, this, &AddressView::addEntry); m_firstName = new QLineEdit(this); m_firstName->resize(m_firstName->sizeHint()); mainGrid->addWidget(m_firstName, 1, 0); firstNameLabel->setBuddy(m_firstName); m_lastName = new QLineEdit(this); m_lastName->resize(m_lastName->sizeHint()); mainGrid->addWidget(m_lastName, 1, 1); lastNameLabel->setBuddy(m_lastName); m_address = new QLineEdit(this); m_address->resize(m_address->sizeHint()); mainGrid->addWidget(m_address, 1, 2); addressLabel->setBuddy(m_address); m_email = new QLineEdit(this); m_email->resize(m_email->sizeHint()); mainGrid->addWidget(m_email, 1, 3); emailLabel->setBuddy(m_email); m_changeButton = new QPushButton(tr("&Change"), this); m_changeButton->resize(m_changeButton->sizeHint()); mainGrid->addWidget(m_changeButton, 1, 4); connect(m_changeButton, &QPushButton::clicked, this, &AddressView::changeEntry); m_treeView = new QTreeView(this); m_treeView->setSelectionMode(QTreeView::SingleSelection); m_treeView->setRootIsDecorated(false); model = new AddressBookModel(this); m_treeView->setModel(model); connect(m_treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &AddressView::itemSelected); mainGrid->addWidget(m_treeView, 2, 0, 1, 5); } void AddressView::updateOutlook() { model->update(); } void AddressView::addEntry() { if (!m_firstName->text().isEmpty() || !m_lastName->text().isEmpty() || !m_address->text().isEmpty() || !m_email->text().isEmpty()) { model->addItem(m_firstName->text(), m_lastName->text(), m_address->text(), m_email->text()); } m_firstName->clear(); m_lastName->clear(); m_address->clear(); m_email->clear(); } void AddressView::changeEntry() { QModelIndex current = m_treeView->currentIndex(); if (current.isValid()) model->changeItem(current, m_firstName->text(), m_lastName->text(), m_address->text(), m_email->text()); } void AddressView::itemSelected(const QModelIndex &index) { if (!index.isValid()) return; QAbstractItemModel *model = m_treeView->model(); m_firstName->setText(model->data(model->index(index.row(), 0)).toString()); m_lastName->setText(model->data(model->index(index.row(), 1)).toString()); m_address->setText(model->data(model->index(index.row(), 2)).toString()); m_email->setText(model->data(model->index(index.row(), 3)).toString()); }
Le reste du fichier met en œuvre l'interface utilisateur en utilisant uniquement les API de Qt, c'est-à-dire sans communiquer directement avec Outlook.
#include "addressview.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); AddressView view; view.setWindowTitle(QObject::tr("Qt Example - Looking at Outlook")); view.show(); return a.exec(); }
La fonction de point d'entrée main() instancie finalement l'interface utilisateur et entre dans la boucle d'événements.
Pour créer l'exemple, vous devez d'abord créer la bibliothèque QAxContainer. Ensuite, exécutez votre outil make dans examples/activeqt/qutlook et exécutez le résultat qutlook.exe.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.