<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Milos Popovic, Author at DMC, Inc.</title>
	<atom:link href="https://static.dmcinfo.com/blog/author/milosp/feed/index.xml" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Wed, 10 Jun 2026 20:51:50 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://static.dmcinfo.com/wp-content/uploads/2025/04/site-icon-150x150.png</url>
	<title>Milos Popovic, Author at DMC, Inc.</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Using QtCharts in a PySide/QML Application</title>
		<link>https://static.dmcinfo.com/blog/17537/using-qtcharts-in-a-pyside-qml-application/</link>
		
		<dc:creator><![CDATA[Milos Popovic]]></dc:creator>
		<pubDate>Wed, 07 Jun 2023 15:46:43 +0000</pubDate>
				<category><![CDATA[Test and Measurement Automation]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/blog/17537/using-qtcharts-in-a-pyside-qml-application/</guid>

					<description><![CDATA[<p>Qt is a popular open-source framework for creating user interfaces for both desktop and mobile applications. PySide is the library of Python bindings for the Qt framework, which allows you to develop dynamic UIs using Python, and is currently the tool of choice for data science. Qt has its own markup language called QML that [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/17537/using-qtcharts-in-a-pyside-qml-application/">Using QtCharts in a PySide/QML Application</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p class="wp-block-paragraph">Qt is a popular open-source framework for creating user interfaces for both desktop and mobile applications. PySide is the library of Python bindings for the Qt framework, which allows you to develop dynamic UIs using Python, and is currently the tool of choice for data science. Qt has its own markup language called QML that we often use to design professional-looking user interfaces quickly and easily. When it comes to graphical elements like graphs, integrating Python and QML can get confusing. In this example, I&rsquo;ll go over how to implement a QtChart object in a PySide6/QML application.&nbsp;&nbsp;</p>

<p class="wp-block-paragraph"><em>Note: this example assumes that you already have a barebones PySide6/QML project set up.</em></p>

<p class="wp-block-paragraph">Let&rsquo;s start with the QML part. Create a <a href="https://doc.qt.io/qt-6/qml-qtcharts-chartview.html" rel="noreferrer noopener" target="_blank">ChartView</a> object inside the QML layout of your choice. Within the ChartView, we will need to create two <a href="https://doc.qt.io/qt-6/qml-qtcharts-valueaxis.html" rel="noreferrer noopener" target="_blank">ValueAxis</a> objects (one for X and one for Y) and an <a href="https://doc.qt.io/qt-6/qml-qtcharts-abstractseries.html" rel="noreferrer noopener" target="_blank">AbstractSeries</a> object. There are a number of different AbstractSeries types to choose from, but we&rsquo;ll go with a <a href="https://doc.qt.io/qt-6/qml-qtcharts-scatterseries.html" rel="noreferrer noopener" target="_blank">ScatterSeries</a> for now. Within the ScatterSeries, designate the ValueAxes as the X and Y axes.</p>

<pre class="”brush:pascal”">
ChartView { //Plot
        id: mainPlot

        //Layout-specific parameters
        Layout.row: 0
        Layout.rowSpan: 2
        Layout.column: 1
        Layout.columnSpan: 2
        Layout.fillHeight: true
        Layout.fillWidth: true
        Layout.preferredWidth: Layout.columnSpan
        Layout.preferredHeight: Layout.rowSpan

        title: &quot;Example Plot&quot;
        legend.visible: false

        ValueAxis {
            id: axisY
            min: 0
            max: 1
            titleText: &quot;Y-Values&quot;
        }

        ValueAxis {
            id: axisX
            min: 0
            max: 20
            titleText: &quot;X-Values&quot;
        }

        ScatterSeries {
            id: plotSeries
            name: &quot;ScatterSeries&quot;
            axisX: axisX
            axisY: axisY
        }
    }
</pre>

<p class="wp-block-paragraph">When you run your application, the ChartView should look something like this:&nbsp;</p>

<p class="wp-block-paragraph" style="text-align: center;"><figure class="wp-block-image"><img decoding="async" alt="QT Example Plot" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/qt-example-plot.png"  /></figure></p>

<p class="wp-block-paragraph">Looks pretty good so far, but there&rsquo;s one major component missing: the data! Python is great for number-crunching and data management, so your application will very likely implement some kind of data model in Python that we will then visualize on our QML UI. For this example, we will make three Qt Signals, one each for adding data, removing data, and scaling the axes.&nbsp;&nbsp;</p>

<pre class="”brush:pascal”">
new_point_added = Signal(QPointF) # add point to graph on test screen from DAQ
clear_graph_requested = Signal() # clear all points from graph
scale_graph_requested = Signal(float, float, int) # send axis scaling to graph
</pre>

<p class="wp-block-paragraph">Then, in the QML file, we will define connections to those Signals. I chose to make these connections in a GridLayout object that contains the ChartView, but it can be done anywhere, as long as the connect() methods execute before the user interacts with the UI. When the GUI receives a &ldquo;new_point_added&rdquo; Signal with a QPointF payload, it will append that point to the ScatterSeries. When it receives a &ldquo;clear_graph_requested&rdquo; Signal, it will clear all the points in the ScatterSeries. Finally, when it receives a &ldquo;scale_graph_requested&rdquo; Signal with a payload of X and Y axis ranges, it will apply those ranges to the ValueAxis objects.&nbsp;&nbsp;</p>

<p class="wp-block-paragraph">The Python object that will emit those signals can be an instance of any class that inherits QObject. For QML to have access to a Python object, you will also need to set it as a &ldquo;context property.&rdquo; For example, the code below allows QML to access a QObject-derived object called my_object using the string &ldquo;main.&rdquo;&nbsp;</p>

<pre class="”brush:pascal”">
qml_app_engine = QQmlApplicationEngine()
qml_context = qml_app_engine.rootContext()
qml_context.setContextProperty(&quot;main&quot;, my_object)
</pre>

<p class="wp-block-paragraph">Now we can connect the signals main.new_point_added, main.clear_graph, and main.scale_graph to slots in QML to manipulate the series and axes. An easy place to make those connections is in the Component.onCompleted slot of some object related to them.</p>

<pre class="”brush:pascal”">
ChartView { //Plot
    Component.onCompleted: {
        main.new_point_added.connect(function (p) {
            plotSeries.append(p.x, p.y)
        })
        main.clear_graph.connect(function() {plotSeries.clear()})
        main.scale_graph.connect(function(ymax, ymin, xmax) {
            axisY.max = ymax
            axisY.min = ymin
            axisX.max = xmax
        })
    }
&hellip;
</pre>

<p class="wp-block-paragraph">Those signals need to be emitted from the Python object that serves as your context property. As an example, the class method below takes in a list of numeric values, scales the graph, and sends the data as a series of points to the QML GUI.</p>

<pre class="”brush:pascal”">
@Slot(list) #clear, scale, and display new data
    def send_data_to_ui(self, dataList):
        self.clear_graph.emit() #clear plot before adding new data

        ySpan = max(dataList) - min(dataList) #calculate x and y axis ranges
        yMid = (max(dataList) + min(dataList)) / 2
        yMax = yMid + (ySpan/2)
        yMin = yMid - (ySpan/2)
        xMax = len(dataList)
        self.scale_graph.emit(yMax, yMin, xMax)

        for i in range(len(dataList)): #loop through data, send each point
            self.new_point_added.emit(QPointF(i, dataList[i]))
</pre>

<p class="wp-block-paragraph">With all the pieces in place, we just need a way to call the send_data_to_ui method from the GUI. In the QML file, create a <a href="https://doc.qt.io/qt-6/qml-qtquick-controls-button.html" rel="noreferrer noopener" target="_blank">Button</a> on the UI that we can use to populate the graph. You can get your data from anywhere, but, for this example, I made a simple start_test function in Python that generates random numbers and feeds it to send_data_to_ui.</p>

<pre class="”brush:pascal”">
Button { //Measure Button
    id: startButton
    Layout.fillHeight: true
    Layout.fillWidth: true
    text: qsTr(&quot;Start Test&quot;)
    onClicked: main.start_test()
}
</pre>

<figure class="wp-block-image"><img decoding="async" alt="START TEST button" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/start-test-button.png"  /></figure>

<p class="wp-block-paragraph">Again, notice that we use &ldquo;main,&rdquo; the name that we gave the context property, to access a method of the object on the Python side. When you run your application and click that button, you&rsquo;ll see something like this in your ChartView:</p>

<figure class="wp-block-image"><img decoding="async" alt="Method of object on the Python side" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/method-of-object-on-python-side.png"  /></figure>

<p class="wp-block-paragraph">Wow, a genuine counterfeit Jackson Pollock painting. Now try playing around with the ChartView parameters. For example, let&rsquo;s change the ScatterSeries to a <a href="https://doc.qt.io/qt-6/qml-qtcharts-lineseries.html" rel="noreferrer noopener" target="_blank">LineSeries</a> and observe the difference:</p>

<figure class="wp-block-image"><img decoding="async" alt="Changed ScatterSeries to a LineSeries" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/changed-scatterseries-to-a-lineseries.png"  /></figure>

<p class="wp-block-paragraph">Congratulations, you can now create flexible, resizable, dynamically updating charts and graphs on (almost) any platform!</p>

<p class="wp-block-paragraph"><strong>Learn more about our <a href="/services/application-development/pc-application-development">PC Application Development</a> and our <a href="/services/test-and-measurement-automation">Test &amp; Measurement Automation</a> expertise, and <a href="/contact">contact us</a> today for your next project.</strong></p>
<p>The post <a href="https://static.dmcinfo.com/blog/17537/using-qtcharts-in-a-pyside-qml-application/">Using QtCharts in a PySide/QML Application</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
