diff --git a/src/appcontext.cpp b/src/appcontext.cpp
index 6ae6b9f..96b4563 100644
--- a/src/appcontext.cpp
+++ b/src/appcontext.cpp
@@ -41,6 +41,9 @@ AppContext::AppContext(Wallet *wallet)
     connect(this->wallet.get(), &Wallet::connectionStatusChanged, [this]{
         this->nodes->autoConnect();
     });
+    connect(this->wallet.get(), &Wallet::currentSubaddressAccountChanged, [this]{
+        this->updateBalance();
+    });
 
     connect(this, &AppContext::createTransactionError, this, &AppContext::onCreateTransactionError);
 
@@ -54,6 +57,10 @@ AppContext::AppContext(Wallet *wallet)
 
     // force trigger preferredFiat signal for history model
     this->onPreferredFiatCurrencyChanged(config()->get(Config::preferredFiatCurrency).toString());
+
+    connect(this->wallet->history(), &TransactionHistory::txNoteChanged, [this]{
+        this->wallet->history()->refresh(this->wallet->currentSubaddressAccount());
+    });
 }
 
 // ################## Transaction creation ##################
diff --git a/src/assets.qrc b/src/assets.qrc
index 8f7488a..9956d8b 100644
--- a/src/assets.qrc
+++ b/src/assets.qrc
@@ -19,6 +19,7 @@
     <file>assets/images/bitcoin.png</file>
     <file>assets/images/camera_dark.png</file>
     <file>assets/images/camera_white.png</file>
+    <file>assets/images/change_account.png</file>
     <file>assets/images/clock1.png</file>
     <file>assets/images/clock2.png</file>
     <file>assets/images/clock3.png</file>
diff --git a/src/assets/images/change_account.png b/src/assets/images/change_account.png
new file mode 100644
index 0000000..f24a4ba
Binary files /dev/null and b/src/assets/images/change_account.png differ
diff --git a/src/dialog/AccountSwitcherDialog.cpp b/src/dialog/AccountSwitcherDialog.cpp
new file mode 100644
index 0000000..dfa66db
--- /dev/null
+++ b/src/dialog/AccountSwitcherDialog.cpp
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) 2020-2021, The Monero Project.
+
+#include "AccountSwitcherDialog.h"
+#include "ui_AccountSwitcherDialog.h"
+
+#include "libwalletqt/SubaddressAccount.h"
+#include "utils/Icons.h"
+#include <QMenu>
+
+AccountSwitcherDialog::AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWidget *parent)
+    : QDialog(parent)
+    , ui(new Ui::AccountSwitcherDialog)
+    , m_ctx(std::move(ctx))
+    , m_model(m_ctx->wallet->subaddressAccountModel())
+{
+    ui->setupUi(this);
+
+    ui->accounts->setContextMenuPolicy(Qt::CustomContextMenu);
+
+    m_ctx->wallet->subaddressAccount()->refresh();
+    ui->accounts->setModel(m_ctx->wallet->subaddressAccountModel());
+    ui->accounts->setSelectionMode(QAbstractItemView::SingleSelection);
+    ui->accounts->setSelectionBehavior(QAbstractItemView::SelectRows);
+    ui->accounts->hideColumn(SubaddressAccountModel::Column::Address);
+    ui->accounts->hideColumn(SubaddressAccountModel::Column::UnlockedBalance);
+    ui->accounts->setColumnWidth(SubaddressAccountModel::Column::Label, 200);
+    ui->accounts->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+    ui->accounts->header()->setSectionResizeMode(SubaddressAccountModel::Label, QHeaderView::Stretch);
+
+    connect(ui->accounts->selectionModel(), &QItemSelectionModel::currentChanged, this, &AccountSwitcherDialog::switchAccount);
+    connect(ui->accounts, &QTreeView::customContextMenuRequested, this, &AccountSwitcherDialog::showContextMenu);
+    connect(ui->accounts, &QTreeView::doubleClicked, [this](QModelIndex index){
+        if (!m_model) return;
+        if (!(m_model->flags(index) & Qt::ItemIsEditable)) {
+            this->switchAccount();
+        }
+    });
+
+    connect(ui->btn_newAccount, &QPushButton::clicked, [this]{
+       m_ctx->wallet->addSubaddressAccount("New account");
+       m_ctx->wallet->subaddressAccount()->refresh();
+    });
+
+    connect(m_ctx->wallet.get(), &Wallet::currentSubaddressAccountChanged, this, &AccountSwitcherDialog::updateSelection);
+    connect(m_ctx->wallet->subaddressAccount(), &SubaddressAccount::refreshFinished, this, &AccountSwitcherDialog::updateSelection);
+
+    this->updateSelection();
+}
+
+void AccountSwitcherDialog::switchAccount() {
+    QModelIndex index = ui->accounts->currentIndex();
+    m_ctx->wallet->switchSubaddressAccount(index.row());
+}
+
+void AccountSwitcherDialog::copyLabel() {
+    auto row = this->currentEntry();
+    if (!row)
+        return;
+
+    Utils::copyToClipboard(QString::fromStdString(row->getLabel()));
+}
+
+void AccountSwitcherDialog::copyBalance() {
+    auto row = this->currentEntry();
+    if (!row)
+        return;
+
+    Utils::copyToClipboard(QString::fromStdString(row->getBalance()));
+}
+
+void AccountSwitcherDialog::editLabel() {
+    QModelIndex index = ui->accounts->currentIndex().siblingAtColumn(m_ctx->wallet->subaddressAccountModel()->Column::Label);
+    ui->accounts->setCurrentIndex(index);
+    ui->accounts->edit(index);
+}
+
+void AccountSwitcherDialog::updateSelection() {
+    qDebug() << "test";
+    QModelIndex index = m_model->index(m_ctx->wallet->currentSubaddressAccount(), 0);
+    ui->accounts->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+}
+
+void AccountSwitcherDialog::showContextMenu(const QPoint &point) {
+    QModelIndex index = ui->accounts->currentIndex();
+    if (!index.isValid()) {
+        return;
+    }
+
+    auto *menu = new QMenu(ui->accounts);
+
+    menu->addAction("Switch to account", this, &AccountSwitcherDialog::switchAccount);
+    menu->addAction("Copy label", this, &AccountSwitcherDialog::copyLabel);
+    menu->addAction("Copy balance", this, &AccountSwitcherDialog::copyBalance);
+    menu->addAction("Edit label", this, &AccountSwitcherDialog::editLabel);
+
+    menu->popup(ui->accounts->viewport()->mapToGlobal(point));
+}
+
+Monero::SubaddressAccountRow* AccountSwitcherDialog::currentEntry() {
+    QModelIndex index = ui->accounts->currentIndex();
+    return m_ctx->wallet->subaddressAccountModel()->entryFromIndex(index);
+}
+
+AccountSwitcherDialog::~AccountSwitcherDialog() {
+    delete ui;
+}
diff --git a/src/dialog/AccountSwitcherDialog.h b/src/dialog/AccountSwitcherDialog.h
new file mode 100644
index 0000000..59cc79b
--- /dev/null
+++ b/src/dialog/AccountSwitcherDialog.h
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) 2020-2021, The Monero Project.
+
+#ifndef FEATHER_ACCOUNTSWITCHERDIALOG_H
+#define FEATHER_ACCOUNTSWITCHERDIALOG_H
+
+#include <QDialog>
+#include "appcontext.h"
+
+#include "model/SubaddressAccountModel.h"
+
+namespace Ui {
+    class AccountSwitcherDialog;
+}
+
+class AccountSwitcherDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit AccountSwitcherDialog(QSharedPointer<AppContext> ctx, QWidget *parent = nullptr);
+    ~AccountSwitcherDialog() override;
+
+private slots:
+    void showContextMenu(const QPoint& point);
+    void updateSelection();
+
+private:
+    void switchAccount();
+    void copyLabel();
+    void copyBalance();
+    void editLabel();
+
+    Monero::SubaddressAccountRow* currentEntry();
+
+    Ui::AccountSwitcherDialog *ui;
+    QSharedPointer<AppContext> m_ctx;
+    SubaddressAccountModel *m_model;
+};
+
+#endif //FEATHER_ACCOUNTSWITCHERDIALOG_H
diff --git a/src/dialog/AccountSwitcherDialog.ui b/src/dialog/AccountSwitcherDialog.ui
new file mode 100644
index 0000000..d332d8e
--- /dev/null
+++ b/src/dialog/AccountSwitcherDialog.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AccountSwitcherDialog</class>
+ <widget class="QDialog" name="AccountSwitcherDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>521</width>
+    <height>275</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Accounts</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTreeView" name="accounts">
+     <property name="focusPolicy">
+      <enum>Qt::NoFocus</enum>
+     </property>
+     <property name="rootIsDecorated">
+      <bool>false</bool>
+     </property>
+     <attribute name="headerStretchLastSection">
+      <bool>false</bool>
+     </attribute>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="QPushButton" name="btn_newAccount">
+       <property name="text">
+        <string>New account</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QDialogButtonBox" name="buttonBox">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="standardButtons">
+        <set>QDialogButtonBox::Ok</set>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>AccountSwitcherDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>AccountSwitcherDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/src/libwalletqt/Coins.cpp b/src/libwalletqt/Coins.cpp
index c275cab..d0440db 100644
--- a/src/libwalletqt/Coins.cpp
+++ b/src/libwalletqt/Coins.cpp
@@ -41,6 +41,10 @@ void Coins::refresh(quint32 accountIndex)
 
         m_pimpl->refresh();
         for (const auto i : m_pimpl->getAll()) {
+            if (i->subaddrAccount() != accountIndex) {
+                continue;
+            }
+
             m_tinfo.append(new CoinsInfo(i, this));
         }
     }
diff --git a/src/libwalletqt/SubaddressAccount.cpp b/src/libwalletqt/SubaddressAccount.cpp
index db885e8..5aa304a 100644
--- a/src/libwalletqt/SubaddressAccount.cpp
+++ b/src/libwalletqt/SubaddressAccount.cpp
@@ -62,3 +62,8 @@ quint64 SubaddressAccount::count() const
 
     return m_rows.size();
 }
+
+Monero::SubaddressAccountRow* SubaddressAccount::row(int index) const
+{
+    return m_rows.value(index);
+}
\ No newline at end of file
diff --git a/src/libwalletqt/SubaddressAccount.h b/src/libwalletqt/SubaddressAccount.h
index e2db11e..7cc380e 100644
--- a/src/libwalletqt/SubaddressAccount.h
+++ b/src/libwalletqt/SubaddressAccount.h
@@ -22,6 +22,7 @@ public:
     Q_INVOKABLE void setLabel(quint32 accountIndex, const QString &label) const;
     Q_INVOKABLE void refresh() const;
     quint64 count() const;
+    Monero::SubaddressAccountRow* row(int index) const;
 
 signals:
     void refreshStarted() const;
diff --git a/src/libwalletqt/TransactionHistory.cpp b/src/libwalletqt/TransactionHistory.cpp
index 42d2349..e355275 100644
--- a/src/libwalletqt/TransactionHistory.cpp
+++ b/src/libwalletqt/TransactionHistory.cpp
@@ -104,7 +104,6 @@ void TransactionHistory::refresh(quint32 accountIndex)
 void TransactionHistory::setTxNote(const QString &txid, const QString &note)
 {
     m_pimpl->setTxNote(txid.toStdString(), note.toStdString());
-    this->refresh(0); // todo: get actual account index
     emit txNoteChanged();
 }
 
diff --git a/src/libwalletqt/TransactionHistory.h b/src/libwalletqt/TransactionHistory.h
index c00a387..15b0ba2 100644
--- a/src/libwalletqt/TransactionHistory.h
+++ b/src/libwalletqt/TransactionHistory.h
@@ -60,6 +60,7 @@ private:
     // history contains locked transfers
     mutable bool m_locked;
 
+    quint32 lastAccountIndex = 0;
 };
 
 #endif // TRANSACTIONHISTORY_H
diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp
index 6edffa2..29bd6c9 100644
--- a/src/libwalletqt/Wallet.cpp
+++ b/src/libwalletqt/Wallet.cpp
@@ -375,6 +375,8 @@ void Wallet::switchSubaddressAccount(quint32 accountIndex)
         }
         m_subaddress->refresh(m_currentSubaddressAccount);
         m_history->refresh(m_currentSubaddressAccount);
+        m_coins->refresh(m_currentSubaddressAccount);
+        this->subaddressModel()->setCurrentSubaddressAcount(m_currentSubaddressAccount);
         emit currentSubaddressAccountChanged();
     }
 }
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index a535881..7be6943 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -20,6 +20,7 @@
 #include "dialog/balancedialog.h"
 #include "dialog/WalletCacheDebugDialog.h"
 #include "dialog/UpdateDialog.h"
+#include "dialog/AccountSwitcherDialog.h"
 #include "constants.h"
 #include "libwalletqt/AddressBook.h"
 #include "utils/AsyncTask.h"
@@ -128,6 +129,10 @@ void MainWindow::initStatusBar() {
     connect(m_statusBtnConnectionStatusIndicator, &StatusBarButton::clicked, this, &MainWindow::showConnectionStatusDialog);
     this->statusBar()->addPermanentWidget(m_statusBtnConnectionStatusIndicator);
 
+    m_statusAccountSwitcher = new StatusBarButton(icons()->icon("change_account.png"), "Account switcher", this);
+    connect(m_statusAccountSwitcher, &StatusBarButton::clicked, this, &MainWindow::showAccountSwitcherDialog);
+    this->statusBar()->addPermanentWidget(m_statusAccountSwitcher);
+
     m_statusBtnPassword = new StatusBarButton(icons()->icon("lock.svg"), "Password", this);
     connect(m_statusBtnPassword, &StatusBarButton::clicked, this, &MainWindow::showPasswordDialog);
     this->statusBar()->addPermanentWidget(m_statusBtnPassword);
@@ -212,6 +217,7 @@ void MainWindow::initMenu() {
 
     // [Wallet]
     connect(ui->actionInformation,  &QAction::triggered, this, &MainWindow::showWalletInfoDialog);
+    connect(ui->actionAccount,      &QAction::triggered, this, &MainWindow::showAccountSwitcherDialog);
     connect(ui->actionPassword,     &QAction::triggered, this, &MainWindow::showPasswordDialog);
     connect(ui->actionSeed,         &QAction::triggered, this, &MainWindow::showSeedDialog);
     connect(ui->actionKeys,         &QAction::triggered, this, &MainWindow::showKeysDialog);
@@ -439,12 +445,13 @@ void MainWindow::onWalletOpened() {
         this->setStatusText("Wallet opened - Searching for node");
 
     // receive page
-    m_ctx->wallet->subaddress()->refresh( m_ctx->wallet->currentSubaddressAccount());
+    m_ctx->wallet->subaddress()->refresh(m_ctx->wallet->currentSubaddressAccount());
     if (m_ctx->wallet->subaddress()->count() == 1) {
         for (int i = 0; i < 10; i++) {
             m_ctx->wallet->subaddress()->addRow(m_ctx->wallet->currentSubaddressAccount(), "");
         }
     }
+    m_ctx->wallet->subaddressModel()->setCurrentSubaddressAcount(m_ctx->wallet->currentSubaddressAccount());
 
     // history page
     m_ctx->wallet->history()->refresh(m_ctx->wallet->currentSubaddressAccount());
@@ -903,6 +910,11 @@ void MainWindow::showWalletCacheDebugDialog() {
     dialog.exec();
 }
 
+void MainWindow::showAccountSwitcherDialog() {
+    AccountSwitcherDialog dialog{m_ctx, this};
+    dialog.exec();
+}
+
 void MainWindow::showNodeExhaustedMessage() {
     // Spawning dialogs inside a lambda can cause system freezes on linux so we have to do it this way ¯\_(ツ)_/¯
 
diff --git a/src/mainwindow.h b/src/mainwindow.h
index e59e4ae..4d14251 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -155,6 +155,7 @@ private slots:
     void showKeysDialog();
     void showViewOnlyDialog();
     void showWalletCacheDebugDialog();
+    void showAccountSwitcherDialog();
 
     void donateButtonClicked();
     void showCalcWindow();
@@ -230,6 +231,7 @@ private:
     ClickableLabel *m_statusLabelBalance;
     QLabel *m_statusLabelStatus;
     QLabel *m_statusLabelNetStats;
+    StatusBarButton *m_statusAccountSwitcher;
     StatusBarButton *m_statusBtnConnectionStatusIndicator;
     StatusBarButton *m_statusBtnPassword;
     StatusBarButton *m_statusBtnPreferences;
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 5d503c8..4ecec6b 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -403,6 +403,7 @@
     <addaction name="actionInformation"/>
     <addaction name="menuAdvanced"/>
     <addaction name="separator"/>
+    <addaction name="actionAccount"/>
     <addaction name="actionPassword"/>
     <addaction name="actionSeed"/>
     <addaction name="actionKeys"/>
@@ -742,6 +743,30 @@
     <string>t</string>
    </property>
   </action>
+  <action name="actiond">
+   <property name="text">
+    <string>d</string>
+   </property>
+  </action>
+  <action name="actionPrimary_account">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Primary account</string>
+   </property>
+  </action>
+  <action name="actionAccount">
+   <property name="text">
+    <string>Account</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
  <customwidgets>
diff --git a/src/model/SubaddressAccountModel.cpp b/src/model/SubaddressAccountModel.cpp
index 8a1f75f..53e9109 100644
--- a/src/model/SubaddressAccountModel.cpp
+++ b/src/model/SubaddressAccountModel.cpp
@@ -7,7 +7,8 @@
 #include <QDebug>
 
 SubaddressAccountModel::SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount)
-    : QAbstractListModel(parent), m_subaddressAccount(subaddressAccount)
+    : QAbstractTableModel(parent)
+    , m_subaddressAccount(subaddressAccount)
 {
     connect(m_subaddressAccount, &SubaddressAccount::refreshStarted, this, &SubaddressAccountModel::startReset);
     connect(m_subaddressAccount, &SubaddressAccount::refreshFinished, this, &SubaddressAccountModel::endReset);
@@ -16,13 +17,26 @@ SubaddressAccountModel::SubaddressAccountModel(QObject *parent, SubaddressAccoun
 void SubaddressAccountModel::startReset(){
     beginResetModel();
 }
+
 void SubaddressAccountModel::endReset(){
     endResetModel();
 }
 
-int SubaddressAccountModel::rowCount(const QModelIndex &) const
+int SubaddressAccountModel::rowCount(const QModelIndex &parent) const
 {
-    return m_subaddressAccount->count();
+    if (parent.isValid()) {
+        return 0;
+    } else {
+        return m_subaddressAccount->count();
+    }
+}
+
+int SubaddressAccountModel::columnCount(const QModelIndex &parent) const
+{
+    if (parent.isValid()) {
+        return 0;
+    }
+    return Column::COUNT;
 }
 
 QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
@@ -32,24 +46,12 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
 
     QVariant result;
 
-    bool found = m_subaddressAccount->getRow(index.row(), [&result, &role](const Monero::SubaddressAccountRow &row) {
-        switch (role) {
-        case SubaddressAccountAddressRole:
-            result = QString::fromStdString(row.getAddress());
-            break;
-        case SubaddressAccountLabelRole:
-            result = QString::fromStdString(row.getLabel());
-            break;
-        case SubaddressAccountBalanceRole:
-            result = QString::fromStdString(row.getBalance());
-            break;
-        case SubaddressAccountUnlockedBalanceRole:
-            result = QString::fromStdString(row.getUnlockedBalance());
-            break;
-        default:
-            qCritical() << "Unimplemented role" << role;
+    bool found = m_subaddressAccount->getRow(index.row(), [this, &index, &result, &role](const Monero::SubaddressAccountRow &row) {
+        if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
+            result = parseSubaddressAccountRow(row, index, role);
         }
     });
+
     if (!found) {
         qCritical("%s: internal error: invalid index %d", __FUNCTION__, index.row());
     }
@@ -57,15 +59,80 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
     return result;
 }
 
-QHash<int, QByteArray> SubaddressAccountModel::roleNames() const
+QVariant SubaddressAccountModel::parseSubaddressAccountRow(const Monero::SubaddressAccountRow &row,
+                                                           const QModelIndex &index, int role) const
 {
-    static QHash<int, QByteArray> roleNames;
-    if (roleNames.empty())
-    {
-        roleNames.insert(SubaddressAccountAddressRole, "address");
-        roleNames.insert(SubaddressAccountLabelRole, "label");
-        roleNames.insert(SubaddressAccountBalanceRole, "balance");
-        roleNames.insert(SubaddressAccountUnlockedBalanceRole, "unlockedBalance");
+    switch (index.column()) {
+        case Number:
+            return QString("#%1").arg(QString::number(index.row()));
+        case Address:
+            return QString::fromStdString(row.getAddress());
+        case Label:
+            return QString::fromStdString(row.getLabel());
+        case Balance:
+            return QString::fromStdString(row.getBalance());
+        case UnlockedBalance:
+            return QString::fromStdString(row.getUnlockedBalance());
+        default:
+            return QVariant();
     }
-    return roleNames;
 }
+
+QVariant SubaddressAccountModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if (role != Qt::DisplayRole) {
+        return QVariant();
+    }
+    if (orientation == Qt::Horizontal)
+    {
+        switch (section) {
+            case Address:
+                return QString("Address");
+            case Label:
+                return QString("Label");
+            case Balance:
+                return QString("Balance");
+            case UnlockedBalance:
+                return QString("Spendable balance");
+            default:
+                return QVariant();
+        }
+    }
+    return QVariant();
+}
+
+bool SubaddressAccountModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+    if (index.isValid() && role == Qt::EditRole) {
+        const int row = index.row();
+
+        switch (index.column()) {
+            case Label:
+                m_subaddressAccount->setLabel(row, value.toString());
+                break;
+            default:
+                return false;
+        }
+        emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
+
+        return true;
+    }
+    return false;
+}
+
+
+Qt::ItemFlags SubaddressAccountModel::flags(const QModelIndex &index) const
+{
+    if (!index.isValid())
+        return Qt::ItemIsEnabled;
+
+    if (index.column() == Label)
+        return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
+
+    return QAbstractTableModel::flags(index);
+}
+
+Monero::SubaddressAccountRow* SubaddressAccountModel::entryFromIndex(const QModelIndex &index) const {
+    Q_ASSERT(index.isValid() && index.row() < m_subaddressAccount->count());
+    return m_subaddressAccount->row(index.row());
+}
\ No newline at end of file
diff --git a/src/model/SubaddressAccountModel.h b/src/model/SubaddressAccountModel.h
index cbc7019..b49f5ba 100644
--- a/src/model/SubaddressAccountModel.h
+++ b/src/model/SubaddressAccountModel.h
@@ -4,35 +4,44 @@
 #ifndef SUBADDRESSACCOUNTMODEL_H
 #define SUBADDRESSACCOUNTMODEL_H
 
-#include <QAbstractListModel>
+#include "Subaddress.h"
+#include <QAbstractTableModel>
 
 class SubaddressAccount;
 
-class SubaddressAccountModel : public QAbstractListModel
+class SubaddressAccountModel : public QAbstractTableModel
 {
     Q_OBJECT
 
 public:
-    enum SubaddressAccountRowRole {
-        SubaddressAccountRole = Qt::UserRole + 1, // for the SubaddressAccountRow object;
-        SubaddressAccountAddressRole,
-        SubaddressAccountLabelRole,
-        SubaddressAccountBalanceRole,
-        SubaddressAccountUnlockedBalanceRole,
+    enum Column {
+        Number,
+        Address,
+        Label,
+        Balance,
+        UnlockedBalance,
+        COUNT
     };
-    Q_ENUM(SubaddressAccountRowRole)
 
     SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount);
 
     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+    int columnCount(const QModelIndex &parent = QModelIndex()) const override;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
-    QHash<int, QByteArray> roleNames() const  override;
+    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+    Qt::ItemFlags flags(const QModelIndex &index) const override;
+
+    bool setData(const QModelIndex &index, const QVariant &value, int role) override;
+
+    Monero::SubaddressAccountRow* entryFromIndex(const QModelIndex &index) const;
 
 public slots:
     void startReset();
     void endReset();
 
 private:
+    QVariant parseSubaddressAccountRow(const Monero::SubaddressAccountRow &row, const QModelIndex &index, int role) const;
+
     SubaddressAccount *m_subaddressAccount;
 };
 
diff --git a/src/model/SubaddressModel.cpp b/src/model/SubaddressModel.cpp
index 7b170b3..bad56e3 100644
--- a/src/model/SubaddressModel.cpp
+++ b/src/model/SubaddressModel.cpp
@@ -11,9 +11,9 @@
 #include <QBrush>
 
 SubaddressModel::SubaddressModel(QObject *parent, Subaddress *subaddress)
-    : QAbstractTableModel(parent),
-    m_subaddress(subaddress),
-    m_showFullAddresses(false)
+    : QAbstractTableModel(parent)
+    , m_subaddress(subaddress)
+    , m_showFullAddresses(false)
 {
     connect(m_subaddress, &Subaddress::refreshStarted, this, &SubaddressModel::startReset);
     connect(m_subaddress, &Subaddress::refreshFinished, this, &SubaddressModel::endReset);
@@ -143,7 +143,7 @@ bool SubaddressModel::setData(const QModelIndex &index, const QVariant &value, i
 
         switch (index.column()) {
             case Label:
-                m_subaddress->setLabel(0, row, value.toString()); // Todo: get actual account index
+                m_subaddress->setLabel(m_currentSubaddressAcount, row, value.toString());
                 break;
             default:
                 return false;
@@ -180,6 +180,10 @@ int SubaddressModel::unusedLookahead() const {
     return m_subaddress->unusedLookahead();
 }
 
+void SubaddressModel::setCurrentSubaddressAcount(quint32 accountIndex) {
+    m_currentSubaddressAcount = accountIndex;
+}
+
 Monero::SubaddressRow* SubaddressModel::entryFromIndex(const QModelIndex &index) const {
     Q_ASSERT(index.isValid() && index.row() < m_subaddress->count());
     return m_subaddress->row(index.row());
diff --git a/src/model/SubaddressModel.h b/src/model/SubaddressModel.h
index 0b8eb0c..3056c02 100644
--- a/src/model/SubaddressModel.h
+++ b/src/model/SubaddressModel.h
@@ -40,6 +40,7 @@ public:
 
     Monero::SubaddressRow* entryFromIndex(const QModelIndex &index) const;
 
+    void setCurrentSubaddressAcount(quint32 accountIndex);
     int unusedLookahead() const;
 
 public slots:
@@ -51,6 +52,7 @@ private:
     QVariant parseSubaddressRow(const Monero::SubaddressRow &subaddress, const QModelIndex &index, int role) const;
 
     bool m_showFullAddresses;
+    quint32 m_currentSubaddressAcount;
 };
 
 #endif // SUBADDRESSMODEL_H