Qutlook Beispiel (ActiveQt)
Das Qutlook-Beispiel demonstriert die Verwendung von ActiveQt zur Automatisierung von Outlook. Das Beispiel verwendet das Tool dumpcpp, um einen C++-Namensraum für die Typbibliothek zu erzeugen, die das Outlook-Objektmodell beschreibt.
Die Projektdatei für das Beispiel sieht wie folgt aus:
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 }
Die Projektdatei verwendet das Tool dumpcpp
, um dem Projekt eine MS Outlook-Typbibliothek hinzuzufügen. Wenn dies fehlschlägt, gibt das generierte Makefile lediglich eine Fehlermeldung aus, andernfalls führt der Build-Schritt nun das Tool dumpcpp für die Typbibliothek aus und generiert einen Header und eine cpp-Datei (in diesem Fall msoutl.h
und msoutl.cpp
), die eine einfach zu verwendende API für die Outlook-Objekte deklarieren und implementieren.
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; };
Die AddressView Klasse ist eine QWidget Unterklasse für die Benutzeroberfläche. Das Widget QTreeView zeigt den Inhalt des Kontaktordners von Outlook an, wie er von model
bereitgestellt wird.
#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; };
Die AddressBookModel-Klasse ist eine QAbstractListModel Unterklasse, die direkt mit Outlook kommuniziert und eine QHash für die Zwischenspeicherung verwendet.
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; } }
Der Konstruktor initialisiert Outlook. Die verschiedenen Signale, die Outlook zur Verfügung stellt, um über Inhaltsänderungen zu informieren, sind mit dem updateOutlook()
Slot verbunden.
AddressBookModel::~AddressBookModel() { delete folderItems; if (!outlook.isNull()) Outlook::NameSpace(outlook.Session()).Logoff(); }
Der Destruktor meldet sich von der Sitzung ab.
int AddressBookModel::rowCount(const QModelIndex &) const { return folderItems ? folderItems->Count() : 0; } int AddressBookModel::columnCount(const QModelIndex & /*parent*/) const { return 4; }
Die Implementierung rowCount()
gibt die von Outlook gemeldete Anzahl der Einträge zurück. columnCount
und headerData
sind so implementiert, dass sie vier Spalten in der Baumansicht anzeigen.
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(); }
Die Implementierung headerData()
gibt hartkodierte Zeichenketten zurück.
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(); }
Die Implementierung von data()
ist der Kern des Modells. Wenn sich die angeforderten Daten im Cache befinden, wird der Wert aus dem Cache verwendet, andernfalls werden die Daten von Outlook abgerufen.
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); }
Der Slot changeItem()
wird aufgerufen, wenn der Benutzer den aktuellen Eintrag über die Benutzeroberfläche ändert. Auf das Outlook-Element wird über die Outlook-API zugegriffen, und es wird über die Eigenschaftssetzer geändert. Schließlich wird das Element in Outlook gespeichert und aus dem Cache entfernt. Beachten Sie, dass das Modell der Ansicht die Datenänderung nicht signalisiert, da Outlook von sich aus ein Signal aussendet.
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(); } }
Der Slot addItem()
ruft die CreateItem-Methode von Outlook auf, um ein neues Kontaktelement zu erstellen, setzt die Eigenschaften des neuen Elements auf die vom Benutzer eingegebenen Werte und speichert das Element.
void AddressBookModel::update() { beginResetModel(); cache.clear(); endResetModel(); }
Der Slot update()
leert den Cache und sendet das Signal reset(), um die Ansicht über die Datenänderung zu informieren, die ein erneutes Zeichnen des Inhalts erfordert.
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()); }
Der Rest der Datei implementiert die Benutzeroberfläche nur mit Qt-APIs, d.h. ohne direkte Kommunikation mit 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(); }
Die main()
-Einstiegspunktfunktion instanziiert schließlich die Benutzeroberfläche und tritt in die Ereignisschleife ein.
Um das Beispiel zu bauen, müssen Sie zuerst die QAxContainer Bibliothek bauen. Führen Sie dann Ihr make-Tool in examples/activeqt/qutlook
aus und starten Sie das resultierende qutlook.exe
.
© 2025 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.