<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[QML does not update when C++ Abstract Model Updates]]></title><description><![CDATA[<p dir="auto">Hello,</p>
<p dir="auto">I am working on a control application for an eight channel preamplifier and am having some troubles integrating QML and C++.  I have an object representing the unit with eight child objects that represent the individual channels.  I am displaying the the channels as a list view, but cannot get the display to update when the channel objects are modified.  For example, I have bound a few boolean variables to button checked properties.  When I toggle the values in the C++ model (reimplemented QAbstractListModel), the button states do not change until I force the ListView to redraw itself by shrinking the window and re-maximizing it.  I originally attempted to use the built-in functionality of the QAbstractListModel to handle the updates, but had not success.  To get to the point I am at, I have implemented a series of signals moving up the object tree until a call can be made to the C++ class to change the fields.  To make the changes go the other way, I have manually sent signals to the QML and have been able to get the preamp status pane to update real time.  Unfortunately I have been unable to do the same for the Channel List View.  Below is some of the source for the project.  Thanks in advance for any help you can provide!</p>
<p dir="auto">main.cpp</p>
<pre><code>#include &lt;QGuiApplication&gt;
#include &lt;QQmlApplicationEngine&gt;
#include &lt;qqmlcontext.h&gt;
#include &lt;qqml.h&gt;
#include &lt;iostream&gt;
#include &lt;QDebug&gt;
#include &lt;QQuickView&gt;
#include &lt;QQmlComponent&gt;
#include &lt;QTimer&gt;
#include "preampmodel.h"

int main(int argc, char *argv[])
{
  QGuiApplication app(argc, argv);
  QTextStream cin(stdin);
  QQmlApplicationEngine engine;
  QQmlContext* context = engine.rootContext();
  PreampModel * preamps = new PreampModel();

  context-&gt;setContextProperty("preampModel", preamps);
  engine.load(QUrl(QStringLiteral("qrc:/MainForm.qml")));
  return app.exec();
}
</code></pre>
<p dir="auto">preampmodel.cpp</p>
<pre><code>/* Class: PreampModel
 * Author: JLimbocker
 * Description:  This class inherits QAbstractListModel to present data to the QML user interface.
 *      It contains eight channels and seven configuration fields.  Each of the eight channels has
 *      eleven roles which are accessed through role names.  The seven configuration fields are accessed
 *      through role names regardless of which index is selected.  This class will be updated when changes
 *      are made in QML and when changes are made in C++.  All changes should be reflected both in QML and
 *      in C++.
 */

#include "preampmodel.h"
#include "channel.h"
#include &lt;QAbstractListModel&gt;
#include &lt;string&gt;
#include &lt;QDebug&gt;

PreampModel::PreampModel(QObject * parent) : QAbstractListModel(parent)
{
  preampID = 1;
  online = true;
  clkStatus = false;
  sampleRate = 2;
  clkSource = 1;
  outFormat = 0;
  clkOutSource = 0;
  for(int i = 0; i &lt; 8; i++)
    channelList.append(new Channel((preampID-1)*8+(1+i), QString("Channel_" + (preampID-1)*8+1), true, false, true, true, 1, 23));
}
PreampModel::~PreampModel()
{

}
/* void PreampModel::print()
 * This function prints debug information for the object
 * Returns: void
 * Parameters: none
 */
void PreampModel::print()
{
  qDebug() &lt;&lt; "PreampID : ";
  qDebug() &lt;&lt; preampID;
  qDebug() &lt;&lt; "\nonline     : ";
  qDebug() &lt;&lt; online;
  qDebug() &lt;&lt; "\nclkStatus  : ";
  qDebug() &lt;&lt; clkStatus;
  qDebug() &lt;&lt; "\nsampleRate : ";
  qDebug() &lt;&lt; sampleRate;
  qDebug() &lt;&lt; "\nclkSource  : ";
  qDebug() &lt;&lt; clkSource;
  qDebug() &lt;&lt; "\noutFormat  : ";
  qDebug() &lt;&lt; outFormat;
  qDebug() &lt;&lt; "\nclkOutSrc  : ";
  qDebug() &lt;&lt; clkOutSource;
  qDebug() &lt;&lt; "\n";
}
/* roleNames()
 * This function is reimplemented from QAbstractItemModel.
 * It provides role names to the QML engine.
 * Returns: roles - a Hash relating the role to the role name
 * Parameters: none
 */
QHash&lt;int, QByteArray&gt; PreampModel::roleNames() const
{
  QHash&lt;int, QByteArray&gt; roles;
  roles[idRole]            = "preampID";
  roles[onlineRole]        = "online";
  roles[clkStatusRole]     = "clkStatus";
  roles[sampleRateRole]    = "sampleRate";
  roles[clkSourceRole]     = "clkSource";
  roles[outFormatRole]     = "outFormat";
  roles[clkOutSourceRole]  = "clkOutSource";
  roles[phantomRole]       = "phantom";
  roles[phaseRole]         = "phase";
  roles[ribbonRole]        = "ribbon";
  roles[groupRole]         = "group";
  roles[groupNameRole]     = "groupName";
  roles[gainRole]          = "gain";
  roles[nameRole]          = "name";
  roles[numberRole]        = "number";
  roles[meterLevelRole]    = "meterLevel";
  roles[peakValueRole]     = "peakValue";
  roles[scribbleStripRole] = "scribbleStrip";
  return roles;
}
/* data(index, role)
 * This function is reimplemented from QAbstractItemModel.
 * It provides access to the model data for the QML Engine.
 * If Index is out of range or the chosen role is not supported,
 * it returns an empty QVariant.
 * Returns: A QVariant containing the desired data, if available.
 * Parameters: index - the index of the data to be accessed
 *             role  - the role of the data to be accessed
 */
QVariant PreampModel::data(const QModelIndex &amp;index, int role) const
{
  if(index.row() &lt; channelList.size() &amp;&amp; index.row() &gt;= 0)
    switch (role){
      case idRole             : return preampID;
      case onlineRole         : return online;
      case clkStatusRole      : return clkStatus;
      case sampleRateRole     : return sampleRate;
      case clkSourceRole      : return clkSource;
      case outFormatRole      : return outFormat;
      case clkOutSourceRole   : return clkOutSource;
      case phantomRole        : return channelList[index.row()]-&gt;getPhantom();
      case phaseRole          : return channelList[index.row()]-&gt;getPhase();
      case ribbonRole         : return channelList[index.row()]-&gt;getRibbon();
      case groupRole          : return channelList[index.row()]-&gt;getGroup();
      case groupNameRole      : return channelList[index.row()]-&gt;getGroupName();
      case gainRole           : return channelList[index.row()]-&gt;getGain();
      case nameRole           : return channelList[index.row()]-&gt;getName();
      case numberRole         : return channelList[index.row()]-&gt;getNumber();
      case meterLevelRole     : return channelList[index.row()]-&gt;getMeterLevel();
      case peakValueRole      : return channelList[index.row()]-&gt;getPeakValue();
      case scribbleStripRole  : return channelList[index.row()]-&gt;getScribbleStrip();
      default: return QVariant();
    }
  else
    return QVariant();
}
/* rowCount(index)
 * This function is reimplemented from QAbstractItemModel.
 * It provides a count of the number of rows in the model.
 * In the case of this implementation, there are only eight
 * different indices - one per preamp channel.
 * Returns: 8 - the number of channels in the preamp.
 * Parameters: index - unused
 */
int PreampModel::rowCount(const QModelIndex &amp; index) const
{
    return 8;
}
/* setData(index, value, role)
 * This function is reimplemented from QAbstractItemModel.
 * It provides an interface for the QML engine to set data
 * fields in the object.
 * Returns: True if data has been set, False otherwise.
 * Parameters: index - the index of the data to be set
 *             value - the value to which the data should be set
 *             role  - the role of the data to be set
 */
bool PreampModel::setData(const QModelIndex &amp; index, const QVariant &amp; value, int role)
{
  if(index.row() &lt; channelList.size() &amp;&amp; index.row() &gt;= 0)
  {
    switch (role){
      case idRole             : preampID     = value.toInt(); break;
      case onlineRole         : online       = value.toBool();break;
      case clkStatusRole      : clkStatus    = value.toBool();break;
      case sampleRateRole     : sampleRate   = value.toInt();break;
      case clkSourceRole      : clkSource    = value.toInt();break;
      case outFormatRole      : outFormat    = value.toInt();break;
      case clkOutSourceRole   : clkOutSource = value.toInt();break;
      case phantomRole        : channelList[index.row()]-&gt;setPhantom(value.toBool());break;
      case phaseRole          : channelList[index.row()]-&gt;setPhase(value.toBool());break;
      case ribbonRole         : channelList[index.row()]-&gt;setRibbon(value.toBool());break;
      case groupRole          : channelList[index.row()]-&gt;setGroup(value.toBool());break;
      case groupNameRole      : channelList[index.row()]-&gt;setGroupName(value.toInt());break;
      case gainRole           : channelList[index.row()]-&gt;setGain(value.toInt());break;
      case nameRole           : channelList[index.row()]-&gt;setName(value.toString());break;
      case numberRole         : channelList[index.row()]-&gt;setNumber(value.toInt());break;
      case meterLevelRole     : channelList[index.row()]-&gt;setMeterLevel(value.toInt());break;
      case peakValueRole      : channelList[index.row()]-&gt;setPeakValue(value.toInt());break;
      case scribbleStripRole  : channelList[index.row()]-&gt;setScribbleStrip(value.toString()); break;
      default: return false;
    }
    qDebug() &lt;&lt; "emitting datachanged";
    //If data has been changed, send signal to notify QML Engine
    emit dataChanged(index, index);
    return true;
  }
  else
    return false;
}
/* index(row, column, parent)
 * This function is reimplemented from QAbstractItemModel.
 * It created an index for the given row and column.
 * Returns: the index corresponding to the row and column
 * Parameters: row - the row at whic the item is located.
 *             column - the column at which the item is located.
 */
QModelIndex PreampModel::index(int row, int column, const QModelIndex &amp;parent) const
{
  return QAbstractItemModel::createIndex(row, column);
}
/* setProperty(_index, name, value)
 * This function provides manual property setting from QML.
 * Returns: True if successful, false if unsuccessful.
 * Parameters: _index - the row to be accessed
 *             name - the role name to be accessed
 *             value - the value to write
 */
bool PreampModel::setProperty( const QVariant _index, const QString name, const QVariant value)
{
  QModelIndex index = PreampModel::index(_index.toInt(), 0, QModelIndex());
  qDebug() &lt;&lt; index.row() &lt;&lt; " " &lt;&lt; name &lt;&lt; " " &lt;&lt; value &lt;&lt; channelList.size();

  if(index.row() &lt; channelList.size() &amp;&amp; index.row() &gt;= 0)
  {
    if(name == QString::fromUtf8("idRole"))
    {
      preampID = value.toInt();
    }
    else if(name == QString::fromUtf8("onlineRole"))
    {
      online = value.toBool();
    }
    else if(name == QString::fromUtf8("clkStatusRole"))
    {
      clkStatus = value.toBool();
    }
    else if(name == QString::fromUtf8("sampleRateRole"))
    {
      sampleRate = value.toInt();
    }
    else if(name == QString::fromUtf8("clkSourceRole"))
    {
      clkSource = value.toInt();
    }
    else if(name == QString::fromUtf8("outFormatRole"))
    {
      outFormat = value.toInt();
    }
    else if(name == QString::fromUtf8("clkOutSourceRole"))
    {
      clkOutSource = value.toInt();
    }
    else if(name == QString::fromUtf8("phantomRole"))
    {
      channelList[index.row()]-&gt;setPhantom(value.toBool());
    }
    else if(name ==  QString::fromUtf8("phaseRole"))
    {
      channelList[index.row()]-&gt;setPhase(value.toBool());
    }
    else if(name ==  QString::fromUtf8("groupRole"))
    {
      channelList[index.row()]-&gt;setGroup(value.toBool());
    }
    else if(name ==  QString::fromUtf8("ribbonRole"))
    {
      channelList[index.row()]-&gt;setRibbon(value.toBool());
    }
    else if(name ==  QString::fromUtf8("groupNameRole"))
    {
      channelList[index.row()]-&gt;setGroupName(value.toInt());
    }
    else if(name ==  QString::fromUtf8("gainRole"))
    {
      channelList[index.row()]-&gt;setGain(value.toInt());
    }
    else if(name ==  QString::fromUtf8("nameRole"))
    {
      channelList[index.row()]-&gt;setName(value.toString());
    }
    else if(name ==  QString::fromUtf8("scribbleStripRole"))
    {
      channelList[index.row()]-&gt;setScribbleStrip(value.toString());
    }
    else
    {
      qDebug() &lt;&lt; "Property Set Failed: Unknown Role";
      return false;
    }
    emit dataChanged(index, index);
    qDebug() &lt;&lt; name &lt;&lt; " changed";
    return true;
  }
  else
  {
    qDebug() &lt;&lt; "Property Set Failed: Index out of Bounds";
    return false;
  }
}
/* flags(index)
 * This function is reimplemented from QAbstractItemModel.
 * It tells the qml that all items are editable and selectable.
 * Returns: An OR combination of the necessary flags.
 * Parameters: index - unused.
 */
Qt::ItemFlags PreampModel::flags(const QModelIndex &amp;index) const
{
  return Qt::ItemIsEditable | Qt::ItemIsSelectable;
}

</code></pre>
<p dir="auto">channel.cpp</p>
<pre><code>Channel::Channel(QObject *parent) : QObject(parent)
{
  phantom = false;
  phase = true;
  ribbon = false;
  group = false;
  groupName = 0;
  gain = 49;
  name = "Channel";
  number = 0;
  meterLevel = 0;
  peakValue = 0;
  scribbleStrip = "";

}
Channel::Channel(int chNum, QString chName, QObject *parent) : QObject(parent)
{
  number = chNum;
  name = chName;
  meterLevel = 0;
  peakValue = 0;
  scribbleStrip = "";
  phantom = false;
  phase = true;
  ribbon = false;
  group = false;
  groupName = 0;
  gain = 49;
}
Channel::Channel(int chNum, QString chName, bool phant, bool pha, bool rib, bool grp, int grpNam, int gn, QObject *parent) : QObject(parent)
{
  number = chNum;
  name = chName;
  meterLevel = 0;
  peakValue = 0;
  scribbleStrip = "";
  phantom = phant;
  phase = pha;
  ribbon = rib;
  group = grp;
  groupName = grpNam;
  gain = gn;
}

//Setters
void Channel::setPhantom(bool newPhantom)
{
  phantom = newPhantom;
  emit phantomChanged();
}
void Channel::setPhase(bool newPhase)
{
  phase = newPhase;
  qDebug() &lt;&lt; "Phase changed at channel level";
  emit phaseChanged();
}
void Channel::setRibbon(bool newRibbon)
{
  ribbon = newRibbon;
  emit ribbonChanged();
}
void Channel::setGroup(bool newGroup)
{
  group = newGroup;
  emit groupChanged();
}
void Channel::setGroupName(int newGroupName)
{
  groupName = newGroupName;
  emit groupNameChanged();
}
void Channel::setGain(int newGain)
{
  gain = newGain;
  emit gainChanged();
}
void Channel::incrementGain()
{
  gain++;
  emit gainChanged();
}
void Channel::decrementGain()
{
  gain--;
  emit gainChanged();
}
void Channel::setName(QString newName)
{
  name = newName;
  emit nameChanged();
}
void Channel::setNumber(int newNumber)
{
  number = newNumber;
  emit numberChanged();
}
void Channel::setMeterLevel(int newLevel)
{
  meterLevel = newLevel;
  emit meterLevelChanged();
}
void Channel::setPeakValue(int newValue)
{
  peakValue = newValue;
  emit peakValueChanged();
}
void Channel::setScribbleStrip(QString newString)
{
  scribbleStrip = newString;
  emit scribbleStripChanged();
}
void Channel::setAll()
{
}
//Getters
bool Channel::getPhantom()
{
  return phantom;
}
bool Channel::getPhase()
{
  return phase;
}
bool Channel::getRibbon()
{
  return ribbon;
}
bool Channel::getGroup()
{
  return group;
}
int Channel::getGroupName()
{
  return groupName;
}
int Channel::getGain()
{
  return gain;
}
QString Channel::getName()
{
  return name;
}
int Channel::getNumber()
{
  return number;
}
int Channel::getMeterLevel()
{
  return meterLevel;
}
int Channel::getPeakValue()
{
  return peakValue;
}
QString Channel::getScribbleStrip()
{
  return scribbleStrip;
}
</code></pre>
<p dir="auto">QML in follow-up post</p>
<p dir="auto">JL</p>
]]></description><link>https://forum.qt.io/topic/69614/qml-does-not-update-when-c-abstract-model-updates</link><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Jul 2026 19:31:20 GMT</lastBuildDate><atom:link href="https://forum.qt.io/topic/69614.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 26 Jul 2016 01:09:37 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to QML does not update when C++ Abstract Model Updates on Tue, 26 Jul 2016 16:14:53 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/cjmdaixi">@<bdi>cjmdaixi</bdi></a><br />
It was my understanding that this operation only needs to occur when the size of the model is being changed, i.e. when rows are being added to the structure.  In this case, I simply want to access data members in the model.  I will implement the begin/endInsertRows and see if it makes a difference.<br />
It is also worth mentioning that I am able to confirm that changes are being made to the C++ model.  The problem seems to be that the QML is not seeing the updates.  I believe a solution would be to find a way to manually update the delegates in the ListView, but there doesn't seem to be a straightforward way to do this.</p>
]]></description><link>https://forum.qt.io/post/339387</link><guid isPermaLink="true">https://forum.qt.io/post/339387</guid><dc:creator><![CDATA[JLimbocker]]></dc:creator><pubDate>Tue, 26 Jul 2016 16:14:53 GMT</pubDate></item><item><title><![CDATA[Reply to QML does not update when C++ Abstract Model Updates on Tue, 26 Jul 2016 09:34:53 GMT]]></title><description><![CDATA[<p dir="auto">according to the Qt Doc, when you want to modify the model, you'd better call the "beginInsertRows" and "endInsertRows" .</p>
]]></description><link>https://forum.qt.io/post/339326</link><guid isPermaLink="true">https://forum.qt.io/post/339326</guid><dc:creator><![CDATA[cjmdaixi]]></dc:creator><pubDate>Tue, 26 Jul 2016 09:34:53 GMT</pubDate></item><item><title><![CDATA[Reply to QML does not update when C++ Abstract Model Updates on Tue, 26 Jul 2016 01:28:15 GMT]]></title><description><![CDATA[<p dir="auto">Last one.  I imagine there is a better way to share the contents of a project, but I am not sure what that would be in this case.</p>
<p dir="auto">Preamp_status.qml</p>
<pre><code>import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0

Rectangle {
  id: rectangle2
  width: 174
  height: 399
  color: "#00000000"
  property bool clkStatus: false;
  property bool online: false;
  property int clkSource
  property int clkOutSource: 0;
  property int outFormat: 0;
  property int sampleRate
  property int devID: 0;
  DropShadow {
    id : adcShadow
    color: qsTr("#df000000")
    source: adc
    horizontalOffset: 2
    verticalOffset: 4
    samples: 6
    radius: 3
    cached: true
    anchors.fill: adc
    visible: adc.visible
  }
  Rectangle {
    id: adc
    color: "#496c88"
    anchors.left: parent.left
    anchors.bottom: parent.bottom
    anchors.right: parent.right
    anchors.top: status.bottom
    anchors.leftMargin: 0
    anchors.bottomMargin: 0
    anchors.rightMargin: 0
    anchors.topMargin: 12
    width: parent.width
    Text {
      id: adcLabel
      height: 22
      color: "#ffffff"
      text: qsTr("ADC")
      verticalAlignment: Text.AlignVCenter
      font.bold: true
      anchors.left: parent.left
      anchors.leftMargin: 6
      anchors.top: parent.top
      anchors.topMargin: 6
      font.pixelSize: 24
    }
    Rectangle {
      id: srRect
      height: 55
      color: "#333240"
      anchors.right: parent.right
      anchors.rightMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      anchors.top: adcLabel.bottom
      anchors.topMargin: 6
      Text {
        id: srLabel
        color: "#ffffff"
        text: qsTr("Sample Rate")
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.top: parent.top
        anchors.topMargin: 3
        font.pixelSize: 14
      }
      ComboBox {
        id: srCombo
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 6
        anchors.top: srLabel.bottom
        anchors.topMargin: 3
        model: srModel
        currentIndex: sampleRate
        Keys.onPressed:
        {
          if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
          {
           srCombo.focus = false
          }
        }
        contentItem: Text {
          color : "#ffffff"
          text: srCombo.displayText
          font.family: "Arial";
          font.pixelSize: 14;
          verticalAlignment: Text.AlignVCenter;
          horizontalAlignment: Text.AlignLeft;
        }
        background: Rectangle{
          color: "#424251"
        }
        indicator: Rectangle { }
        delegate: ItemDelegate {
          x: 0
          y: 0
          width:srCombo.width
          contentItem: Text {
            text:modelData;
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignVCenter
            font.family: "Arial";
            font.pixelSize: 14;
            color: "#ffffff"
          }
          onClicked:
          {
            sampleRate = index
            srCombo.focus = false
          }
        }
        popup: Popup {
          id: srPopup
          width: srCombo.width
          height:srView.contentHeight 
          margins: 0
          background: Rectangle { color: "#424251" }
          contentItem: ListView {
            id: srView
            anchors.fill: parent
            model:srCombo.model
            boundsBehavior: Flickable.StopAtBounds
            highlight: Rectangle { color: "#69697C" }
            spacing: 0
            highlightFollowsCurrentItem: true
            currentIndex:sampleRate
            delegate:srCombo.delegate
          }
          enter: Transition {
            SequentialAnimation {
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: 0; to: srView.contentHeight }
              PropertyAction { properties: "contentItem.visible"; value: true }
            }
          }
          exit: Transition {
            SequentialAnimation{
              PropertyAction { properties: "contentItem.visible"; value: false }
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: srView.contentHeight; to: 0 }
            }
          }
        }
        textRole: "key"
        ListModel
        {
          id: srModel
          ListElement { key: "44.1 kHz"; }
          ListElement { key: "48 kHz"; }
          ListElement { key: "88.2 kHz"; }
          ListElement { key: "96 kHz"; }
          ListElement { key: "176.4 kHz"; }
          ListElement { key: "196 kHz"; }
        }
      }
    }
    Rectangle {
      id: clkSrcRect
      height: 55
      color: "#333240"
      anchors.top: srRect.bottom
      anchors.topMargin: 6
      anchors.right: parent.right
      anchors.rightMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      Text {
        id: clkSrcLabel
        color: "#ffffff"
        text: qsTr("Clock Source")
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.top: parent.top
        anchors.topMargin: 3
        font.pixelSize: 14
      }
      ComboBox {
        id: clkSrcCombo
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 6
        anchors.top: clkSrcLabel.bottom
        anchors.topMargin: 3
        model:clkSrcModel
        currentIndex: clkSource
        Keys.onPressed:
        {
          if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
          {
           clkSrcCombo.focus = false
          }
        }
        contentItem: Text {
          color : "#ffffff"
          text: clkSrcCombo.displayText
          font.family: "Arial";
          font.pixelSize: 14;
          verticalAlignment: Text.AlignVCenter;
          horizontalAlignment: Text.AlignLeft;
        }
        background: Rectangle{
          color: "#424251"
        }
        indicator: Rectangle { }
        delegate: ItemDelegate {
          width:clkSrcCombo.width
          contentItem: Text {
            text:modelData;
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignVCenter
            font.family: "Arial";
            font.pixelSize: 14;
            color: "#ffffff"
          }
          onClicked:
          {
            clkSource = index;
            clkSrcCombo.focus = false
          }
        }
        popup: Popup {
          id:clkSrcPopup
          width: clkSrcCombo.width
          height: clkSrcView.contentHeight 
          margins: 0
          background: Rectangle { color: "#424251" }
          contentItem: ListView {
            id: clkSrcView
            anchors.fill: parent
            model:clkSrcCombo.model
            boundsBehavior: Flickable.StopAtBounds
            highlight: Rectangle { color: "#69697C" }
            spacing: 0
            highlightFollowsCurrentItem: true
            currentIndex:clkSource
            delegate:clkSrcCombo.delegate
          }
          enter: Transition {
            SequentialAnimation {
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: 0; to: clkSrcView.contentHeight }
              PropertyAction { properties: "contentItem.visible"; value: true }
            }
          }
          exit: Transition {
            SequentialAnimation{
              PropertyAction { properties: "contentItem.visible"; value: false }
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: clkSrcView.contentHeight; to: 0 }
            }
          }
        }
        textRole: "key"
        ListModel
        {
          id:clkSrcModel
          ListElement { key: "Internal"; }
          ListElement { key: "Word"; }
          ListElement { key: "Word - 75Ω"; }
          ListElement { key: "Dante"; }
        }
      }
    }
    Rectangle {
      id: outRect
      height: 55
      color: "#333240"
      anchors.right: parent.right
      anchors.rightMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      anchors.top: clkSrcRect.bottom
      anchors.topMargin: 6
      Text {
        id: outLabel
        color: "#ffffff"
        text: qsTr("Output Format")
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.top: parent.top
        anchors.topMargin: 3
        font.pixelSize: 14
      }
      ComboBox {
        id: outCombo
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 6
        anchors.top: outLabel.bottom
        anchors.topMargin: 3
        model:outModel
        currentIndex: outFormat
        Keys.onPressed:
        {
          if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
          {
           outCombo.focus = false
          }
        }
        contentItem: Text {
          color : "#ffffff"
          text: outCombo.displayText
          font.family: "Arial";
          font.pixelSize: 14;
          verticalAlignment: Text.AlignVCenter;
          horizontalAlignment: Text.AlignLeft;
        }
        background: Rectangle{
          color: "#424251"
        }
        indicator: Rectangle { }
        delegate: ItemDelegate {
          width:outCombo.width
          contentItem: Text {
            text:modelData;
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignVCenter
            font.family: "Arial";
            font.pixelSize: 14;
            color: "#ffffff"
          }
          onClicked:
          {
            outFormat = index
            outCombo.focus = false
          }
        }
        popup: Popup {
          id:outPopup
          width: outCombo.width
          height : outView.contentHeight /*parent.height*parent.count*/
          margins: 0
          background: Rectangle { color: "#424251" }
          contentItem: ListView {
            id: outView
            anchors.fill: parent
            model:outCombo.model
            boundsBehavior: Flickable.StopAtBounds
            highlight: Rectangle { color: "#69697C" }
            spacing: 0
            highlightFollowsCurrentItem: true
            currentIndex:outFormat
            delegate:outCombo.delegate
          }
          enter: Transition {
            SequentialAnimation {
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: 0; to:outView.contentHeight }
              PropertyAction { properties: "contentItem.visible"; value: true }
            }
          }
          exit: Transition {
            SequentialAnimation{
              PropertyAction { properties: "contentItem.visible"; value: false }
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from:outView.contentHeight; to: 0 }
            }
          }
        }
        textRole: "key"
        ListModel
        {
          id:outModel
          ListElement { key: "Professional"; }
          ListElement { key: "Consumer"; }
        }
      }
    }
    Rectangle {
      id: clkOutRect
      height: 55
      color: "#333240"
      anchors.right: parent.right
      anchors.rightMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      anchors.top: outRect.bottom
      anchors.topMargin: 6
      Text {
        id: clkOutLabel
        color: "#ffffff"
        text: qsTr("Clock Out Source")
        anchors.top: parent.top
        anchors.topMargin: 3
        anchors.left: parent.left
        anchors.leftMargin: 6
        font.pixelSize: 14
      }
      ComboBox {
        id: clkOutCombo
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 6
        anchors.top: clkOutLabel.bottom
        anchors.topMargin: 3
        model:clkOutModel
        currentIndex: clkOutSource
        Keys.onPressed:
        {
          if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
          {
           clkOutCombo.focus = false;
          }
        }
        contentItem: Text {
          color : "#ffffff"
          text: clkOutCombo.displayText
          font.family: "Arial";
          font.pixelSize: 14;
          verticalAlignment: Text.AlignVCenter;
          horizontalAlignment: Text.AlignLeft;
        }
        background: Rectangle{
          color: "#424251"
        }
        indicator: Rectangle { }
        delegate: ItemDelegate {
          width:clkOutCombo.width
          contentItem: Text {
            text:modelData;
            horizontalAlignment: Text.AlignLeft
            verticalAlignment: Text.AlignVCenter
            font.family: "Arial";
            font.pixelSize: 14;
            color: "#ffffff"
          }
          onClicked:
          {
            clkOutSource = index
            clkOutCombo.focus = false
          }
        }
        popup: Popup {
          id: clkOutPopup
          width: clkOutCombo.width
          height: clkOutView.contentHeight /*parent.height*parent.count*/
          //implicitHeight:clkOutView.contentHeight
          margins: 0
          background: Rectangle { color: "#424251" }
          contentItem: ListView {
            id:clkOutView
            anchors.fill: parent

            model:clkOutCombo.model
            boundsBehavior: Flickable.StopAtBounds
            highlight: Rectangle { color: "#69697C" }
            spacing: 0
            highlightFollowsCurrentItem: true
            currentIndex:clkOutSource
            delegate:clkOutCombo.delegate
          }
          enter: Transition {
            SequentialAnimation {
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: 0; to: clkOutView.contentHeight }
              PropertyAction { properties: "contentItem.visible"; value: true }
            }
          }
          exit: Transition {
            SequentialAnimation{
              PropertyAction { properties: "contentItem.visible"; value: false }
              PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: clkOutView.contentHeight; to: 0 }
            }
          }
        }
        textRole: "key"
        ListModel
        {
          id:clkOutModel
          ListElement { key: "Internal"; }
          ListElement { key: "External"; }
        }
      }
    }
    Rectangle {
      id: clkStatusRect
      height: 30
      color: "#333240"
      anchors.top: clkOutRect.bottom
      anchors.topMargin: 6
      anchors.right: parent.right
      anchors.rightMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      Text {
        id: clkStatusLabel
        color: "#ffffff"
        text: qsTr("Clock Status")
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.verticalCenter: parent.verticalCenter
        font.pixelSize: 14
      }
      Rectangle {
        id: clkStatusIndicator
        x: 86
        y: 8
        width: 16
        height: 16
        color: clkStatus ? "#00ff00" : "#767676"
        radius: 8
        anchors.right: parent.right
        anchors.rightMargin: 16
        anchors.verticalCenter: parent.verticalCenter
      }
    }
  }
  DropShadow {
    id : statusShadow
    color: qsTr("#df000000")
    source: status
    horizontalOffset: 2
    verticalOffset: 4
    samples: 6
    radius: 3
    anchors.rightMargin: 0
    anchors.bottomMargin: 0
    anchors.leftMargin: 0
    anchors.topMargin: 0
    cached: true
    anchors.fill: status
    visible: status.visible
  }
  Rectangle {
    id: status
    height: 73
    color: "#496c88"
    anchors.top: parent.top
    anchors.topMargin: 0
    anchors.right: parent.right
    anchors.rightMargin: 0
    anchors.left: parent.left
    anchors.leftMargin: 0
    Rectangle {
      id: statusRect
      y: 39
      color: "#333240"
      anchors.left: statusLabel.right
      anchors.leftMargin: 6
      anchors.bottom: parent.bottom
      anchors.bottomMargin: 6
      anchors.top: parent.top
      anchors.right: parent.right
      anchors.topMargin: 6
      anchors.rightMargin: 6
      Rectangle {
        id: onlineIndicator
        x: 138
        y: 16
        width: 16
        height: 16
        color: online ? "#00ff00" : "#767676"
        radius: 8
        anchors.verticalCenter: onlineLabel.verticalCenter
        anchors.right: parent.right
        anchors.rightMargin: 6
        Layout.maximumHeight: 16
        Layout.maximumWidth: 16
        Layout.minimumHeight: 16
        Layout.minimumWidth: 16
        Layout.preferredHeight: 16
        Layout.preferredWidth: 16
      }
      Text {
        id: onlineLabel
        y: 0
        color: "#ffffff"
        text: qsTr("Online")
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 6
        anchors.right: onlineIndicator.left
        anchors.rightMargin: 6
        verticalAlignment: Text.AlignVCenter
        Layout.columnSpan: 6
        Layout.rowSpan: 1
        Layout.fillHeight: true
        font.pixelSize: 18
      }
      Text {
        id: preampID
        y: 0
        color: "#ffffff"
        text: devID
        anchors.verticalCenterOffset: -15
        anchors.verticalCenter: parent.verticalCenter
        anchors.left: idLabel.right
        anchors.leftMargin: 6
        verticalAlignment: Text.AlignVCenter
        Layout.columnSpan: 3
        Layout.rowSpan: 1
        Layout.fillHeight: true
        font.pixelSize: 18
      }
      Text {
        id: idLabel
        color: "#ffffff"
        text: qsTr("ID:")
        anchors.top: parent.top
        anchors.topMargin: 6
        anchors.verticalCenterOffset: -15
        anchors.verticalCenter: parent.verticalCenter
        anchors.left: parent.left
        anchors.leftMargin: 5
        verticalAlignment: Text.AlignVCenter
        Layout.columnSpan: 3
        Layout.fillHeight: true
        font.pixelSize: 18
      }
    }
    Text {
      id: statusLabel
      width: 72
      height: 25
      color: "#ffffff"
      text: "Status"
      anchors.top: parent.top
      anchors.topMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      font.bold: true
      verticalAlignment: Text.AlignVCenter
      font.pixelSize: 22
    }
    Button {
      id: pkClearButton
      anchors.right: statusRect.left
      anchors.rightMargin: 6
      anchors.top: statusLabel.bottom
      anchors.topMargin: 6
      anchors.bottom: parent.bottom
      anchors.bottomMargin: 6
      anchors.left: parent.left
      anchors.leftMargin: 6
      background: pkClearBackgroundLoader.item
      contentItem: Text {
        color: "#ffffff"
        text: "Peak Clear"
        font.pixelSize: 12
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
      }

      Loader {
        id: pkClearBackgroundLoader
        sourceComponent: pkClearButton.pressed ? pkClearClicked : pkClearNormal
      }
      Component {
        id: pkClearNormal
        Rectangle { gradient: Gradient { GradientStop { position: 0.0; color: "#69697C" } GradientStop { position: 1.0; color: "#424251" } } }
      }
      Component {
        id: pkClearClicked
        Rectangle { gradient: Gradient { GradientStop { position: 0.0; color: "#3e3e46" } GradientStop { position: 1.0; color: "#1f1f24" } } }
      }

    }
  }
}</code></pre>
]]></description><link>https://forum.qt.io/post/339275</link><guid isPermaLink="true">https://forum.qt.io/post/339275</guid><dc:creator><![CDATA[JLimbocker]]></dc:creator><pubDate>Tue, 26 Jul 2016 01:28:15 GMT</pubDate></item><item><title><![CDATA[Reply to QML does not update when C++ Abstract Model Updates on Tue, 26 Jul 2016 01:22:45 GMT]]></title><description><![CDATA[<p dir="auto">Channel.qml</p>
<pre><code>import QtQuick 2.7
import QtQuick.Controls 2.0
import QtGraphicalEffects 1.0

Rectangle {
  id: channel
  property var gainVal: 49
  property var gainDisp: valToDisp(gainVal)
  property var channelID: "#"
  property var channelName: "ChannelName"
  property var peakValue: false
  property var groupName
  property var group
  property var ribbon
  property var phantom
  property var phase
  property var meterLevel
  property var scribbleStrip

  onPhantomChanged: console.log("Delegate Phantom Changed")
  onPhaseChanged:   console.log("Delegate Phase Changed")
  onGroupChanged:   console.log("Group Changed")
  onRibbonChanged:  console.log("Ribbon Changed")
  onGroupNameChanged: console.log("Group Name Changed")
  onGainValChanged: console.log("Gain Changed")
  function valToDisp(val)
  {
    return (val*1 &lt;= 0) ?  -6: val*1+1
  }
  function updateGain(change)
  {
    gainVal = gainVal + change;
    if(gainVal &gt; 68)
      gainVal = 68;
    if(gainVal &lt; 0)
      gainVal = 0;
    gainSlider.value = gainVal;
  }
  function updateGainValue(value)
  {
    if(value*1 &gt; 68)
      gainVal = 68;
    else if(value*1 &lt; 0)
      gainVal = 0;
    else
      gainVal = value;
    gainSlider.value = gainVal;
  }
  DropShadow {
    id : channelShadow
    color: qsTr("#df000000")
    source: channel
    horizontalOffset: 2
    verticalOffset: 4
    samples: 6
    radius: 3
    cached: true
    anchors.fill: channel
    visible: channel.visible
  }
  width: 174
  height: 399
  color: "#00000000"
  Rectangle {
    id: rectangle1
    x: 212
    y: 133
    width: 174
    height: 344
    color:  "#496c89"
    anchors.rightMargin: 0
    anchors.fill: parent

    GridView {
      id: gridView1
      anchors.right: parent.right
      anchors.rightMargin: 0
      anchors.left: parent.left
      anchors.leftMargin: 0
      anchors.bottom: parent.bottom
      anchors.bottomMargin: 0
      anchors.top: parent.top
      anchors.topMargin: 0
      cellHeight: 70
      cellWidth: 70

      Rectangle {
        id: channelRect
        width: 120
        height: 74
        color: "#333240"
        anchors.top: parent.top
        anchors.topMargin: 6
        anchors.right: meterRect.left
        anchors.rightMargin: 6
        anchors.left: parent.left
        anchors.leftMargin: 6

        Text {
          id: channelIDField
          height: 31
          color: "#ffffff"
          text: channelID
          anchors.right: parent.right
          anchors.rightMargin: 6
          anchors.left: channelNameField.left
          anchors.leftMargin: 6
          anchors.top: parent.top
          anchors.topMargin: 6
          font.pixelSize: 30
          font.bold: true
          horizontalAlignment: Text.AlignLeft
          verticalAlignment: Text.AlignVCenter
        }
        TextField {
          id: channelNameField
          text: channelName
          font.bold: false
          anchors.right: parent.right
          anchors.rightMargin: 3
          anchors.left: parent.left
          anchors.leftMargin: 3
          anchors.bottom: parent.bottom
          anchors.bottomMargin: 6
          anchors.top: channelIDField.bottom
          anchors.topMargin: 0
          font.pixelSize: 15
          selectByMouse: true
          verticalAlignment: TextInput.AlignVCenter
          horizontalAlignment: TextInput.AlignLeft
          validator: RegExpValidator { regExp: /([A-Za-z0-9-_]{1,11})/; }
          background: channelNameBackgroundLoader.item
          color: focus ? "#26c9ff" : "#ffffff"
          selectionColor: "#26c9ff"
          selectedTextColor: "#ffffff"
          Component {
            id: nameFieldNormal
            Rectangle { color: "#333240" }
          }
          Component {
            id: nameFieldSelected
            Rectangle { color: "#636378" }
          }
          Loader {
            id: channelNameBackgroundLoader
            sourceComponent: nameFieldNormal
          }
          onFocusChanged:
          {
            if(focus)
            {
              selectAll();
              channelNameBackgroundLoader.sourceComponent = nameFieldSelected
            }
            else
            {
              channelNameBackgroundLoader.sourceComponent = nameFieldNormal
            }
          }
          onEditingFinished:
          {
            channelName = text;
            text: channelName;
            focus = false;
            channelNameBackgroundLoader.sourceComponent = nameFieldNormal
          }
        }
      }
      Rectangle {
        id: gainRect
        x: 7
        height: 153
        color: "#333240"
        anchors.top: channelRect.bottom
        anchors.topMargin: 6
        anchors.rightMargin: 0
        anchors.leftMargin: 0
        anchors.right: channelRect.right
        anchors.left: channelRect.left

        Text {
          id: gainLabel
          width: 40
          color: "#ffffff"
          text: "Gain"
          anchors.bottom: gainUp.top
          anchors.bottomMargin: 6
          font.pixelSize: 20
          horizontalAlignment: Text.AlignHCenter
          verticalAlignment: Text.AlignVCenter
          anchors.left: parent.left
          anchors.leftMargin: 6
          anchors.top: parent.top
          anchors.topMargin: 6
        }
        TextField {
          id: gainDisplay
          text: gainDisp
          echoMode: TextInput.Normal
          anchors.left: gainLabel.right
          anchors.leftMargin: 6
          anchors.right: parent.right
          anchors.rightMargin: 6
          anchors.bottom: gainUp.top
          anchors.bottomMargin: 6
          anchors.top: parent.top
          anchors.topMargin: 6
          horizontalAlignment: Text.AlignHCenter
          verticalAlignment: TextInput.AlignVCenter
          font.pixelSize: 28
          selectByMouse:true
          validator: IntValidator { bottom: -6; top: 69} //TODO Change behavior on entered fields
          background: gainDisplayBackgroundLoader.item
          color: focus ? "#26c9ff" : "#ffffff";
          selectionColor: "#26c9ff"
          selectedTextColor: "#ffffff"
          Loader {
            id: gainDisplayBackgroundLoader
            sourceComponent: gainDisplayNormal
          }
          Component {
            id: gainDisplayNormal
            Rectangle { color: "#333240"; }
          }
          Component {
            id: gainDisplaySelected
            Rectangle { color: "#636378"; }
          }
          onFocusChanged:
          {
            if(focus)
            {
              selectAll();
              gainDisplayBackgroundLoader.sourceComponent = gainDisplaySelected
              gainSlider.visible = true;
            }
            else
            {
              gainDisplayBackgroundLoader.sourceComponent = gainDisplayNormal;
            }
          }
          onEditingFinished:
          {
            gainSlider.visible = false;
            if(gainDisplay.text*1 &lt; 0)
            {
              updateGainValue(0);
            }
            else if (gainDisplay.text*1 &lt; 2)
            {
              updateGainValue(1);
            }
            else
              updateGainValue(gainDisplay.text*1 - 1);
            focus = false;
            gainDisplayBackgroundLoader.sourceComponent = gainDisplayNormal
          }
        }
        Button {
          id: gainUp
          y: 57
          width: 90
          height: 40
          anchors.left: parent.left
          anchors.leftMargin: 6
          anchors.horizontalCenterOffset: 0
          anchors.horizontalCenter: parent.horizontalCenter
          background: gainUpBackgroundLoader.item
          contentItem: gainUpContentLoader.item
          Loader {
            id: gainUpBackgroundLoader
            sourceComponent: gainUpNormal
          }
          Loader {
            id: gainUpContentLoader
            sourceComponent: upArrow
          }
          Component {
            id: gainUpNormal
            Rectangle { gradient: Gradient { GradientStop { position: 0.0; color: "#69697C" } GradientStop { position: 1.0; color: "#424251" } } }
          }
          Component {
            id: gainUpClicked
            Rectangle { gradient: Gradient { GradientStop { position: 0.0; color: "#3e3e46" } GradientStop { position: 1.0; color: "#1f1f24" } } }
          }
          Component {
            id: upArrow
            Image {
              source: "Images/upArrow.png"
              width: 27
              height: 20
              fillMode: Image.Pad
            }
          }
          Component {
            id: upArrowClicked
            Image {
              source: "Images/upArrowClicked.png"
              fillMode: Image.Pad
            }
          }
          Timer {
            id: gainUpLongpress
            repeat: false
            running: false
            interval: 500
            onTriggered: { gainUpRepeat.restart() }
          }
          Timer {
            id: gainUpRepeat
            repeat: true
            running: false
            interval: 250
            onTriggered: { updateGain(1);  }
          }
          MouseArea {
            id: mouseArea1
            x: 18
            y: 16
            anchors.fill: parent
            hoverEnabled: true
            onPressed:
            {
              updateGain(1);
              gainUpLongpress.restart();
              gainUpBackgroundLoader.sourceComponent = gainUpClicked
              gainUpContentLoader.sourceComponent = upArrowClicked
            }
            onReleased:
            {
              gainUpLongpress.stop();
              gainUpRepeat.stop();
              gainUpBackgroundLoader.sourceComponent = gainUpNormal
              gainUpContentLoader.sourceComponent = upArrow
            }
            onExited:
            {
              gainUpLongpress.stop();
              gainUpRepeat.stop();
              gainUpBackgroundLoader.sourceComponent = gainUpNormal
              gainUpContentLoader.sourceComponent = upArrow
            }
            onCanceled:
            {
              gainUpLongpress.stop();
              gainUpRepeat.stop();
              gainUpBackgroundLoader.sourceComponent = gainUpNormal
              gainUpContentLoader.sourceComponent = upArrow
            }
          }
        }
        Button {
          id: gainDown
          width: 90
          height: 40
          anchors.top: gainUp.bottom
          anchors.topMargin: 6
          anchors.left: parent.left
          anchors.leftMargin: 6
          anchors.horizontalCenterOffset: 0
          anchors.horizontalCenter: parent.horizontalCenter
          contentItem: gainDownContentLoader.item
          background: gainDownBackgroundLoader.item
          Loader {
            id: gainDownBackgroundLoader
            sourceComponent: gainDownNormal
          }
          Loader {
            id: gainDownContentLoader
            sourceComponent: downArrow
          }
          Component {
            id: gainDownNormal
            Rectangle { gradient: Gradient { GradientStop { position: 0.0; color: "#69697C" } GradientStop { position: 1.0; color: "#424251" } } }
          }
          Component {
            id: gainDownClicked
            Rectangle { gradient: Gradient { GradientStop { position: 0.00; color: "#3e3e46"; } GradientStop { position: 1.00; color: "#1f1e24"; } } }
          }
          Component {
            id: downArrow
            Image {
              source: "Images/downArrow.png"
              width: 27
              height: 20
              fillMode: Image.Pad
            }
          }
          Component {
            id: downArrowClicked
            Image {
              source: "Images/downArrowClicked.png"
              fillMode: Image.Pad
            }
          }
          Timer {
            id: gainDownLongpress
            repeat: false
            running: false
            interval: 500
            onTriggered: { gainDownRepeat.restart() }
          }
          Timer {
            id: gainDownRepeat
            repeat: true
            running: false
            interval: 250
            onTriggered: { updateGain(-1) }
          }
          MouseArea {
            id: mouseArea2
            anchors.rightMargin: 0
            anchors.bottomMargin: -1
            anchors.leftMargin: 0
            anchors.topMargin: 1
            anchors.fill: parent
            hoverEnabled: true
            onPressed:
            {
              updateGain(-1);
              gainDownLongpress.restart();
              gainDownBackgroundLoader.sourceComponent = gainDownClicked
              gainDownContentLoader.sourceComponent = downArrowClicked
            }
            onReleased:
            {
              gainDownLongpress.stop();
              gainDownRepeat.stop();
              gainDownBackgroundLoader.sourceComponent = gainDownNormal
              gainDownContentLoader.sourceComponent = downArrow
            }
            onExited:
            {
              gainDownLongpress.stop();
              gainDownRepeat.stop();
              gainDownBackgroundLoader.sourceComponent = gainDownNormal
              gainDownContentLoader.sourceComponent = downArrow
            }
            onCanceled:
            {
              gainDownLongpress.stop();
              gainDownRepeat.stop();
              gainDownBackgroundLoader.sourceComponent = gainDownNormal
              gainDownContentLoader.sourceComponent = downArrow
            }
          }
        }
      }
      Rectangle {
        id: groupRect
        y: 293
        height: 43
        color: "#333240"
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.left: channelRect.left
        anchors.leftMargin: 0
        Button {
          id: btnGroup
          y: 3
          width: 55
          height: 33
          text: qsTr("")
          checkable: true
          checked: group
          anchors.verticalCenter: parent.verticalCenter
          anchors.left: parent.left
          anchors.leftMargin: 6
          background: groupLoader.item
          contentItem: Text {
            color: "#ffffff"
            text: "group"
            font.pixelSize: 16
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
          }
          onCheckedChanged:
          {
            if(checked)
              groupLoader.sourceComponent = grpStyleON
            else
              groupLoader.sourceComponent = grpStyleOFF
          }
          onClicked:
          {
            group = !group;
          }
          Loader {
            id: groupLoader
            sourceComponent: grpStyleOFF
          }
          Component {
            id: grpStyleON
            Rectangle { gradient: Gradient { GradientStop { position: 1; color: "#2db201" } GradientStop { position: 0; color: "#238c01" } } }
          }
          Component {
            id: grpStyleOFF
            Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#69697C" } GradientStop { position: 1; color: "#424251" } } }
          }
        }
        ComboBox {
          id: groupSelect
          y: 3
          width: 85
          height: 33
          model: groupList
          currentIndex: groupName
          anchors.verticalCenter: parent.verticalCenter
          anchors.right: parent.right
          anchors.rightMargin: 6
          anchors.left: btnGroup.right
          anchors.leftMargin: 6
          Keys.onPressed:
          {
            if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
            {
              groupSelect.focus = false
            }
          }
          contentItem: Text {
            color : "#ffffff"
            text: parent.displayText
            font.family: "Arial";
            font.pixelSize: 16;
            verticalAlignment: Text.AlignVCenter;
            horizontalAlignment: Text.AlignLeft;
          }
          background: Rectangle{
            color: "#424251"
          }
          indicator: Rectangle { }
          delegate: ItemDelegate {
            width: groupSelect.width
            contentItem: Text {
              text:modelData;
              horizontalAlignment: Text.AlignHCenter
              verticalAlignment: Text.AlignVCenter
              font.family: "Arial";
              font.pixelSize: 16;
              color: "#ffffff"
            }
            onClicked:
            {
              groupName = index
              groupSelect.focus = false
            }
          }
          popup: Popup {
            id: groupPopup
            width: groupSelect.width
            height:listview.contentHeight 
            margins: 0
            background: Rectangle { color: "#424251" }
            contentItem: ListView {
              id: listview
              anchors.fill: parent
              model: groupSelect.model
              boundsBehavior: Flickable.StopAtBounds
              highlight: Rectangle { color: "#69697C" }
              spacing: 0
              highlightFollowsCurrentItem: true
              currentIndex: groupSelect.highlightedIndex
              delegate: groupSelect.delegate
            }
            enter: Transition {
              SequentialAnimation {
                PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: 0; to: listview.contentHeight }
                PropertyAction { properties: "contentItem.visible"; value: true }
              }
            }
            exit: Transition {
              SequentialAnimation{
                PropertyAction { properties: "contentItem.visible"; value: false }
                PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: listview.contentHeight; to: 0 }
              }
            }
          }
          textRole: "key"
          ListModel
          {
            id: groupList
            ListElement { key: "Group 1"; }
            ListElement { key: "Group 2"; }
            ListElement { key: "Group 3"; }
          }
        }
      }
      Rectangle {
        id: configRect
        height: 44
        color: "#333240"
        anchors.bottom: groupRect.top
        anchors.bottomMargin: 6
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.left: parent.left
        anchors.leftMargin: 6
        Row {
          id: configRow
          spacing: 6
          anchors.right: parent.right
          anchors.rightMargin: 6
          anchors.left: parent.left
          anchors.leftMargin: 6
          anchors.top: parent.top
          anchors.topMargin: 6
          anchors.bottom: parent.bottom
          anchors.bottomMargin: 6
          Button {
            id: btnPhantom
            width: (parent.width-parent.spacing*2)/3
            text: qsTr("")
            checkable: true
            checked: phantom
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 0
            anchors.top: parent.top
            anchors.topMargin: 0
            background: phantomLoader.item
            contentItem: Text {
              color: "#ffffff"
              text: "48V"
              font.pixelSize: 16
              verticalAlignment: Text.AlignVCenter
              horizontalAlignment: Text.AlignHCenter
            }
            Loader {
              id: phantomLoader
              sourceComponent: phantomStyleOFF
            }
            onCheckedChanged:
            {
              if(checked)
                phantomLoader.sourceComponent = phantomStyleON
              else
                phantomLoader.sourceComponent = phantomStyleOFF
            }
            onClicked:
            {
             phantom = !phantom;
             checked = phantom;
            }
            Component {
              id: phantomStyleON 
              Rectangle { gradient: Gradient { GradientStop { position: 1; color: "#d93600" } GradientStop { position: 0; color: "#8c2300" } } }
            }
            Component {
              id: phantomStyleOFF
              Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#69697C" } GradientStop { position: 1; color: "#424251" } } }
            }
          }
          Button {
            id: btnPhase
            width: (parent.width-parent.spacing*2)/3
            text: qsTr("")
            state: "OFF"
            checkable: true
            checked: phase
            anchors.bottom: parent.bottom
            anchors.top: parent.top
            anchors.bottomMargin: 0
            anchors.topMargin: 0
            contentItem: Text {
              color: "#ffffff"
              text: "Ø"
              font.pixelSize: 16
              verticalAlignment: Text.AlignVCenter
              horizontalAlignment: Text.AlignHCenter
            }
            background: phaseLoader.item
            Loader{
              id: phaseLoader
              sourceComponent: phaseStyleOFF
            }
            onCheckedChanged:
            {
              if(checked)
                phaseLoader.sourceComponent = phaseStyleON
              else
                phaseLoader.sourceComponent = phaseStyleOFF
            }
            onClicked:
            {
              phase = !phase;
              checked: phase;
            }
            Component {
              id: phaseStyleON
              Rectangle { gradient: Gradient { GradientStop { position: 1; color: "#d9a300" } GradientStop { position: 0; color: "#8c6900" } } }
            }
            Component {
              id: phaseStyleOFF
              Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#69697C" } GradientStop { position: 1; color: "#424251" } } }
            }
          }
          Button {
            id: btnRibbon
            width: (parent.width-parent.spacing*2)/3
            text: qsTr("")
            checkable: true
            checked: ribbon
            anchors.bottom: parent.bottom
            anchors.top: parent.top
            anchors.bottomMargin: 0
            anchors.topMargin: 0
            background: ribbonLoader.item
            contentItem: Text {
              color: "#ffffff"
              text: "RBN"
              font.pixelSize: 16
              verticalAlignment: Text.AlignVCenter
              horizontalAlignment: Text.AlignHCenter
            }
            Loader {
              id: ribbonLoader
              sourceComponent: ribbonStyleOFF
            }
            onCheckedChanged:
            {
              if(checked)
                ribbonLoader.sourceComponent = ribbonStyleON
              else
                ribbonLoader.sourceComponent = ribbonStyleOFF
            }
            onClicked:
            {
              ribbon = !ribbon;
              checked: ribbon;
            }
            Component {
              id: ribbonStyleON
              Rectangle { gradient: Gradient { GradientStop { position: 1; color: "#006dd9" } GradientStop { position: 0; color: "#00468c" } } }
            }
            Component {
              id: ribbonStyleOFF
              Rectangle { gradient: Gradient { GradientStop { position: 0; color: "#69697C" } GradientStop { position: 1; color: "#424251" } } }
            }
          }
        }
      }
      Rectangle {
        id: meterRect
        width: 46
        color: "#333240"
        anchors.topMargin: 6
        anchors.rightMargin: 6
        anchors.left: gainRect.right
        anchors.leftMargin: 6
        anchors.bottom: gainRect.bottom
        anchors.top: parent.top
        anchors.right: parent.right
        Meter {
          id: meter
          color: "#333240"
          anchors.topMargin: 0
          anchors.fill: parent
        }
      }
      DropShadow {
        id : sliderShadow
        color: qsTr("#df000000")
        source: gainSlider
        horizontalOffset: 3
        verticalOffset: 6
        samples: 16
        radius: 8
        cached: true
        anchors.fill: gainSlider
        visible: gainSlider.visible
      }
      Slider {
        id: gainSlider
        visible: false
        focusPolicy: Qt.NoFocus
        width: 55
        height: 300
        anchors.top: channelRect.bottom
        anchors.topMargin: 0
        anchors.leftMargin: 6
        anchors.bottomMargin: 10
        snapMode: Slider.SnapAlways
        stepSize: 1
        from: 0
        to: 68
        orientation: Qt.Vertical
        background:  Rectangle {
          x: gainSlider.leftPadding
          y: gainSlider.topPadding
          implicitWidth: 50
          implicitHeight: 300
          width: gainSlider.availableWidth
          height: gainSlider.availableHeight
          color: "#333240"; border.width: 3; border.color: "#898989";
          Rectangle{
            color: "#898989"
            //height: parent.height
            width: 6
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.top: parent.top
            anchors.bottom: parent.bottom
            anchors.topMargin: 12
            anchors.bottomMargin: 12
          }
        }
        handle:  Image {
          x: gainSlider.leftPadding + gainSlider.availableWidth/2 - width/2
          y: gainSlider.topPadding + gainSlider.visualPosition * (gainSlider.availableHeight - height)
          source: "/Images/fader_vert_png.png"; height: 26; width: 33
        }
        Component.onCompleted:
        {
          value = gainVal
        }
        onPositionChanged:
        {
          value = Math.floor(value)
          updateGainValue(Math.floor(gainSlider.position*69));
        }
      }
      Rectangle {
        id: rectangle2
        color: "#333240"
        z: -1
        anchors.left: parent.left
        anchors.leftMargin: 6
        anchors.right: parent.right
        anchors.rightMargin: 6
        anchors.top: groupRect.bottom
        anchors.topMargin: 6
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 6
        TextArea {
          id: scribbleBox
          x: 41
          y: 32
          width: 80
          height: 20
          color: focus ? "#26c9ff" : "#ffffff";
          bottomPadding: 3
          rightPadding: 3
          topPadding: 3
          leftPadding: 3
          wrapMode: Text.NoWrap
          clip: false
          selectionColor: "#26c9ff"
          selectedTextColor: "#ffffff"
          placeholderText: qsTr("notes...")
          anchors.rightMargin: 3
          anchors.leftMargin: 3
          anchors.bottomMargin: 3
          anchors.topMargin: 3
          anchors.fill: parent
          background: scribbleBackgroundLoader.item
          selectByMouse:true
          font.pixelSize: 14
          text: scribbleStrip
          Loader {
            id: scribbleBackgroundLoader
            sourceComponent: scribbleNormal
          }
          onFocusChanged:
          {
            if(focus)
            {
              selectAll();
              scribbleBackgroundLoader.sourceComponent = scribbleSelected
            }
            else
            {
              color: "#ffffff";
              scribbleBackgroundLoader.sourceComponent = scribbleNormal
            }
          }
          Keys.onPressed:
          {
            if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
            {
              console.log("Enter")
              if(lineCount == 2)
              {
                console.log("Line count = 2")
                event.accepted = true
              }
            }
          }
          onEditingFinished:
          {
            focus = false;
            scribbleBackgroundLoader.sourceComponent = scribbleNormal;
            scribbleStrip = text;
          }
          Component {
            id: scribbleNormal
            Rectangle { anchors.fill: parent; color: "#333240"; }
          }
          Component {
            id: scribbleSelected
            Rectangle { anchors.fill: parent; color: "#636378"; }
          }
        }
      }
    }
  }
}
</code></pre>
]]></description><link>https://forum.qt.io/post/339273</link><guid isPermaLink="true">https://forum.qt.io/post/339273</guid><dc:creator><![CDATA[JLimbocker]]></dc:creator><pubDate>Tue, 26 Jul 2016 01:22:45 GMT</pubDate></item><item><title><![CDATA[Reply to QML does not update when C++ Abstract Model Updates on Tue, 26 Jul 2016 01:15:06 GMT]]></title><description><![CDATA[<p dir="auto">Preamp.qml</p>
<pre><code>import QtQuick 2.7
import QtQuick.Layouts 1.1
import QtQuick.Controls 2.0

Rectangle {
  id: pre
  property var devName: "preamp";
  property int devID: 0;
  property int clkSource
  property int clkOutSource
  property int outFormat
  property int sampleRate
  property bool online
  property bool clkStatus
  property variant channelModel
  property int startChNum: (devID-1)*8 + 1;

  signal channelChange(var index, var prop, var value)

  height: 410
  width: parent.width
  color: "#00000000"
  ListView {
    Component.onCompleted:
    {
      currentIndex = 0;
    }
    id: channelView
    anchors.left: parent.left
    anchors.right: status.left
    anchors.rightMargin: 12
    contentWidth: 1488
    contentHeight: 400
    boundsBehavior: Flickable.StopAtBounds
    flickableDirection: Flickable.AutoFlickIfNeeded
    orientation: ListView.Horizontal
    interactive: true
    spacing: 12
    delegate: Channel {
      id: ch
      channelID: model.number;
      channelName: model.name;
      gainVal: model.gain;
      phantom: model.phantom;
      phase: model.phase;
      ribbon: model.ribbon;
      group: model.group;
      groupName: model.groupName;
      meterLevel: model.meterLevel;
      scribbleStrip: model.scribbleStrip;
      onPhantomChanged:
      {
        pre.channelChange(model.modelIndex, "phantomRole", phantom)
        channelView.currentIndex = index;
      }
      onPhaseChanged:
      {
        pre.channelChange(index, "phaseRole", phase)
        channelView.currentIndex = index;
      }
      onGroupChanged:
      {
        pre.channelChange(index, "groupRole", group)
        channelView.currentIndex = index;
      }
      onRibbonChanged:
      {
        pre.channelChange(index, "ribbonRole", ribbon)
        channelView.currentIndex = index;
      }
      onGroupNameChanged:
      {
        pre.channelChange(index, "groupNameRole", groupName)
        channelView.currentIndex = index;
      }
      onGainValChanged:
      {
        pre.channelChange(index, "gainRole", gainVal)
        channelView.currentIndex = index;
      }
      onChannelNameChanged:
      {
        pre.channelChange(index, "nameRole", channelName)
        channelView.currentIndex = index;
      }
      onScribbleStripChanged:
      {
        pre.channelChange(index, "scribbleStripRole", scribbleStrip)
        channelView.currentIndex = index;
      }
    }
    model: channelModel
    ScrollBar.horizontal: ScrollBar {
    }
  }
  Preamp_status {
    id: status
    anchors.top: parent.top
    anchors.right: parent.right
    anchors.rightMargin: 6
    anchors.leftMargin: 12
    online: parent.online
    clkStatus: parent.clkStatus
    clkSource: parent.clkSource
    clkOutSource: parent.clkOutSource
    sampleRate: parent.sampleRate
    outFormat: parent.outFormat
    devID: parent.devID
    onSampleRateChanged:
    {
      pre.channelChange(channelView.CurrentIndex, "sampleRateRole", sampleRate)
    }
    onOnlineChanged:
    {
      pre.channelChange(channelView.currentIndex, "onlineRole", online)
    }
    onClkStatusChanged:
    {
      pre.channelChange(channelView.currentIndex, "clkStatusRole", clkStatus)
    }
    onClkSourceChanged:
    {
      pre.channelChange(channelView.currentIndex, "clkSourceRole", clkSource)
    }
    onClkOutSourceChanged:
    {
      pre.channelChange(channelView.currentIndex, "clkOutSourceRole", clkOutSource)
    }
    onOutFormatChanged:
    {
      pre.channelChange(channelView.currentIndex, "outFormatRole", outFormat)
    }
  }
}
</code></pre>
<p dir="auto">MainForm.qml</p>
<pre><code>import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
Window {
  id:top
  visible: true
  Connections
  {
    target: preampModel
    onDataChanged:{
      preamp1.devID = preampModel.preampID;
      preamp1.devName = "";
      preamp1.clkSource = preampModel.clkSource
      preamp1.clkOutSource = preampModel.clkOutSource
      preamp1.outFormat =preampModel.outFormat
      preamp1.sampleRate = preampModel.sampleRate
      preamp1.online = preampModel.online
      preamp1.clkStatus = preampModel.clkStatus
      preamp1.channelModel = preampModel
      preamp1.updated();
    }
  }
  Rectangle {
    id: main
    objectName: "mainRect"
    anchors.fill: parent
    color: "#505050"
    Rectangle {
      id: navBar
      anchors.top: parent.top
      width: parent.width*(7/12)
      height: 60
      z: 10
      color: "#000000"
      Row {
        id: row1
        x: parent.x
        y: parent.y
        width: parent.width
        height: parent.height
        Rectangle {
          id: preampsBtn
          width: parent.width/3
          height: parent.height
          color: parent.parent.color
          Text {
            id: preampTxt
            x: 40
            y: 9
            width: 240
            height: 43
            color: "#ffffff"
            text: qsTr("Preamp")
            font.pixelSize: 26
            anchors.fill: parent
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
          }
          MouseArea {
            id: mouseArea_preamps
            width: 100
            height: 100
            anchors.fill: parent
          }
        }
        Rectangle {
          id: mixerBtn
          width: parent.width/3
          height: parent.height
          color: parent.parent.color
          Text {
            id: mixerTxt
            x: 40
            y: 9
            width: 240
            height: 43
            color: "#ffffff"
            text: "Mixer"
            font.pixelSize: 26
            anchors.fill: parent
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
          }
          MouseArea {
            id: mouseArea_mixer
            width: 100
            height: 100
            anchors.fill: parent
          }
        }
        Rectangle {
          id: setupBtn
          width: parent.width/3
          height: parent.height
          color: parent.parent.color
          Text {
            id: setupTxt
            x: 40
            y: 9
            width: 240
            height: 43
            color: "#ffffff"
            text: qsTr("Setup")
            font.pixelSize: 26
            anchors.fill: parent
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
          }
          MouseArea {
            id: mouseArea_setup
            width: 100
            height: 100
            anchors.fill: parent
          }
        }
      }
    }
    Rectangle {
      id: presetBar
      x: parent.width - width
      y: 0
      width: parent.width *(5/12)-20
      height: 60
      z:10
      color: "#000000"
      Row {
        id: row2
        x: 268
        y: 24
        width: 200
        height: 400
        anchors.fill: parent
        Rectangle {
          id: rectangle1
          width: parent.width*(3/14)
          height: parent.height
          color: parent.parent.color
          Text {
            id: text4
            color: "#ffffff"
            text: qsTr("Preset")
            font.pixelSize: 26
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            anchors.fill: parent
          }
        }
        Rectangle {
          id: rectangle2
          width: parent.width*(5/14)
          height: parent.height
          color: parent.parent.color
          ComboBox {
            id: presetBox
            y: 3
            model: presetList
            anchors.fill:parent
            anchors.margins: 3
            Keys.onPressed:
            {
              if(event.key == Qt.Key_Enter || event.key == Qt.Key_Return)
              {
                presetBox.focus = false
              }
            }
            contentItem: Text {
              color : "#496c89"
              text: presetBox.displayText
              font.family: "Arial";
              font.pixelSize: 26;
              verticalAlignment: Text.AlignVCenter;
              horizontalAlignment: Text.AlignHCenter;
            }
            background: Rectangle{
              color: "#16161d"
            }
            indicator: Rectangle { }
            delegate: ItemDelegate {
              width: presetBox.width
              contentItem: Text {
                text: modelData;
                horizontalAlignment: Text.AlignHCenter
                verticalAlignment: Text.AlignVCenter
                font.family: "Arial";
                font.pixelSize: 26;
                color: "#7a9cb8"
              }
              onClicked:
              {
                presetBox.currentIndex = index
                preamplistview.currentIndex = index
                presetBox.focus = false
              }
            }
            popup: Popup {
              id: preampPopup
              width: parent.width
              height: preamplistview.contentHeight
              margins: 0
              background: Rectangle { color: "#16161d" }
              contentItem: ListView {
                id: preamplistview
                anchors.fill: parent
                model: presetBox.model
                boundsBehavior: Flickable.StopAtBounds
                highlight: Rectangle { color: "#69697C" }
                spacing: 0
                highlightFollowsCurrentItem: true
                currentIndex: presetBox.highlightedIndex
                delegate: presetBox.delegate
              }
              enter: Transition {
                PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: 0; to: preampPopup.parent.height*preampPopup.parent.count }
              }
              exit: Transition {
                PropertyAnimation { properties: "height"; easing.type: Easing.OutSine; duration: 250; from: preampPopup.parent.height*preampPopup.parent.count; to: 0 }
              }
            }
            textRole: "key"
            ListModel
            {
              id: presetList
              ListElement { key: "Defaults"; }
              ListElement { key: "Preset 1"; }
              ListElement { key: "Preset 2"; }
            }
          }
        }
        Rectangle {
          id: rectangle3
          width: parent.width*(3/14)
          height: parent.height
          color: parent.parent.color
          Text {
            id: text5
            x: 277
            y: 23
            color: "#ffffff"
            text: qsTr("store")
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            anchors.fill: parent
            font.pixelSize: 26
          }
        }
        Rectangle {
          id: rectangle4
          width: parent.width*(3/14)
          height: parent.height
          color: parent.parent.color
          Text {
            id: text6
            color: "#ffffff"
            text: qsTr("recall")
            anchors.fill: parent
            verticalAlignment: Text.AlignVCenter
            horizontalAlignment: Text.AlignHCenter
            font.pixelSize: 26
          }
        }
      }
    }
    function updateModel(index, role, value)
    {
      preampModel.setProperty(index, role, value)
      //console.log("Model Updated")
    }
    Preamp {
      id: preamp1
      devID: preampModel.preampID;
      devName: "";
      clkSource: preampModel.clkSource
      clkOutSource: preampModel.clkOutSource
      outFormat:preampModel.outFormat
      sampleRate: preampModel.sampleRate
      online: preampModel.online
      clkStatus: preampModel.clkStatus
      channelModel: preampModel
      anchors.right: parent.right
      anchors.rightMargin: 0
      anchors.left: parent.left
      anchors.leftMargin: 6
      anchors.top: navBar.bottom
      anchors.topMargin: 6
      anchors.bottom: parent.bottom
      anchors.bottomMargin: 6
      onChannelChange:
      {
          main.updateModel(index, prop, value)
      }
    }
  }
}
</code></pre>
]]></description><link>https://forum.qt.io/post/339272</link><guid isPermaLink="true">https://forum.qt.io/post/339272</guid><dc:creator><![CDATA[JLimbocker]]></dc:creator><pubDate>Tue, 26 Jul 2016 01:15:06 GMT</pubDate></item></channel></rss>