diff options
author | Johnathan Corgan <johnathan@corganlabs.com> | 2015-04-02 15:14:13 -0700 |
---|---|---|
committer | Johnathan Corgan <johnathan@corganlabs.com> | 2015-04-02 15:14:13 -0700 |
commit | f0076a4996c3f9a5a53f88a0413e434fe3968525 (patch) | |
tree | 6b4bfbfd063dcbf1e9387d2dd396d930828f5ede | |
parent | 2d56b2261d5cfaacc51f6c2e651f9f45a10a5462 (diff) | |
parent | 04faaba502eaa78e87463ca66c1a681bc17c5869 (diff) |
Merge branch 'master' into next
-rw-r--r-- | cmake/Packaging/Fedora-15.cmake | 2 | ||||
-rw-r--r-- | cmake/Packaging/Fedora-16.cmake | 2 | ||||
-rw-r--r-- | cmake/Packaging/Fedora-17.cmake | 2 | ||||
-rw-r--r-- | cmake/Packaging/Fedora-18.cmake | 2 | ||||
-rw-r--r-- | docs/doxygen/other/build_guide.dox | 1 | ||||
-rw-r--r-- | gr-qtgui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-qtgui/doc/qtgui.dox | 1 | ||||
-rw-r--r-- | gr-qtgui/grc/qtgui_range.xml | 130 | ||||
-rw-r--r-- | gr-qtgui/python/qtgui/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-qtgui/python/qtgui/__init__.py | 3 | ||||
-rwxr-xr-x | gr-qtgui/python/qtgui/range.py | 157 |
11 files changed, 173 insertions, 129 deletions
diff --git a/cmake/Packaging/Fedora-15.cmake b/cmake/Packaging/Fedora-15.cmake index 18836d871b..c86dbedbd8 100644 --- a/cmake/Packaging/Fedora-15.cmake +++ b/cmake/Packaging/Fedora-15.cmake @@ -1,6 +1,6 @@ SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs") SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt") -SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt") +SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4") SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah") SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy") SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL") diff --git a/cmake/Packaging/Fedora-16.cmake b/cmake/Packaging/Fedora-16.cmake index 18836d871b..c86dbedbd8 100644 --- a/cmake/Packaging/Fedora-16.cmake +++ b/cmake/Packaging/Fedora-16.cmake @@ -1,6 +1,6 @@ SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs") SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt") -SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt") +SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4") SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah") SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy") SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL") diff --git a/cmake/Packaging/Fedora-17.cmake b/cmake/Packaging/Fedora-17.cmake index 23e3334ab9..ee5460702c 100644 --- a/cmake/Packaging/Fedora-17.cmake +++ b/cmake/Packaging/Fedora-17.cmake @@ -1,6 +1,6 @@ SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs") SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt") -SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt") +SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4") SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah") SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy" "PyOpenGL") SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL") diff --git a/cmake/Packaging/Fedora-18.cmake b/cmake/Packaging/Fedora-18.cmake index 23e3334ab9..ee5460702c 100644 --- a/cmake/Packaging/Fedora-18.cmake +++ b/cmake/Packaging/Fedora-18.cmake @@ -1,6 +1,6 @@ SET(PACKAGE_DEPENDS_CORE_RUNTIME "fftw-libs") SET(PACKAGE_DEPENDS_QTGUI_RUNTIME "qt" "qwt") -SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4" "PyQwt") +SET(PACKAGE_DEPENDS_QTGUI_PYTHON "PyQt4") SET(PACKAGE_DEPENDS_GRC "python" "numpy" "gtk2" "python-lxml" "python-cheetah") SET(PACKAGE_DEPENDS_WXGUI "wxGTK" "python" "numpy" "PyOpenGL") SET(PACKAGE_DEPENDS_VIDEO_SDL_RUNTIME "SDL") diff --git a/docs/doxygen/other/build_guide.dox b/docs/doxygen/other/build_guide.dox index ee07e6355c..c21b9874ac 100644 --- a/docs/doxygen/other/build_guide.dox +++ b/docs/doxygen/other/build_guide.dox @@ -50,7 +50,6 @@ first. Most recent systems have these packages available. \li qt4 (>= 4.4.0) http://qt.nokia.com/downloads/ \li qwt (>= 5.2.0) http://sourceforge.net/projects/qwt/ \li pyqt (>= 4.10.0) http://www.riverbankcomputing.co.uk/software/pyqt/download -\li pyqwt* (>= 5.2.0) http://pyqwt.sourceforge.net/download.html \subsection dep_gr_wxgui gr-wxgui: The WX-based Graphical User Interface \li wxpython (>= 2.8) http://www.wxpython.org/ diff --git a/gr-qtgui/CMakeLists.txt b/gr-qtgui/CMakeLists.txt index 13cbfb2e1f..ad832b94a1 100644 --- a/gr-qtgui/CMakeLists.txt +++ b/gr-qtgui/CMakeLists.txt @@ -38,7 +38,6 @@ include(GrComponent) if(NOT CMAKE_CROSSCOMPILING) set(qt_gui_python_deps PYQT4_FOUND - #we could check for pyqwt, but its not strictly required ) endif(NOT CMAKE_CROSSCOMPILING) diff --git a/gr-qtgui/doc/qtgui.dox b/gr-qtgui/doc/qtgui.dox index 1d4c3099a3..3cce328f9a 100644 --- a/gr-qtgui/doc/qtgui.dox +++ b/gr-qtgui/doc/qtgui.dox @@ -132,7 +132,6 @@ The QT GUI blocks require the following dependencies. \li QtOpenGL (version >= 4.4) \li PyQt4 for Qt4 (version >= 4.4) \li Qwt (version >= 5.2) -\li PyQwt5 for Qt4 (version >= 5.2) \section qtgui_usage Usage diff --git a/gr-qtgui/grc/qtgui_range.xml b/gr-qtgui/grc/qtgui_range.xml index 2896d081ab..6546dfc357 100644 --- a/gr-qtgui/grc/qtgui_range.xml +++ b/gr-qtgui/grc/qtgui_range.xml @@ -8,130 +8,16 @@ <block> <name>QT GUI Range</name> <key>variable_qtgui_range</key> - <import>from PyQt4 import Qt</import> - <import>from PyQt4.QtCore import QObject, pyqtSlot</import> - <import>import PyQt4.Qwt5 as Qwt</import> + <import>from gnuradio.qtgui import Range, RangeWidget</import> <var_make>self.$(id) = $(id) = $value</var_make> - <make>#set $win = 'self._%s_layout'%$id + <make>#set $win = 'self._%s_win'%$id #if not $label() #set $label = '"%s"'%$id #end if -######################################################################## -#if $widget() == "knob" -######################################################################## -$win = Qt.QVBoxLayout() -self._$(id)_knob = Qwt.QwtKnob() -self._$(id)_knob.setRange($start, $stop, $step) -self._$(id)_knob.setValue(self.$id) -self._$(id)_knob.valueChanged.connect(self.set_$(id)) -$(win).addWidget(self._$(id)_knob) -self._$(id)_label = Qt.QLabel($label) -self._$(id)_label.setAlignment(Qt.Qt.AlignTop | Qt.Qt.AlignHCenter) -$(win).addWidget(self._$(id)_label) -#end if -######################################################################## -#if $widget() == "thermo" -######################################################################## -$win = Qt.QVBoxLayout() -self._$(id)_label = Qt.QLabel($label) -self._$(id)_thermo = Qwt.QwtThermo() -self._$(id)_thermo.setScalePosition(Qwt.QwtThermo.$orient.scalepos) -self._$(id)_thermo.setRange($start, $stop) -self._$(id)_thermo.setValue(self.$id) -self._$(id)_thermo.$(orient.minfcn)($min_len) -#if 'horizontal' in $orient().lower() -self._$(id)_label.setAlignment(Qt.Qt.AlignBottom | Qt.Qt.AlignHCenter) -$(win).addWidget(self._$(id)_label) -$(win).addWidget(self._$(id)_thermo) -#elif 'vertical' in $orient().lower() -self._$(id)_label.setAlignment(Qt.Qt.AlignTop) -$(win).addWidget(self._$(id)_thermo) -$(win).addWidget(self._$(id)_label) -#end if -#end if -######################################################################## -#if $widget() == "counter" -######################################################################## -$win = Qt.QHBoxLayout() -$(win).addWidget(Qt.QLabel($label+": ")) -class qwt_counter_pyslot(Qwt.QwtCounter): - def __init__(self, parent=None): - Qwt.QwtCounter.__init__(self, parent) - @pyqtSlot('double') - def setValue(self, value): - super(Qwt.QwtCounter, self).setValue(value) -self._$(id)_counter = qwt_counter_pyslot() -self._$(id)_counter.setRange($start, $stop, $step) -self._$(id)_counter.setNumButtons(2) -self._$(id)_counter.setMinimumWidth($min_len) -self._$(id)_counter.setValue(self.$id) -$(win).addWidget(self._$(id)_counter) -self._$(id)_counter.valueChanged.connect(self.set_$(id)) -#end if -######################################################################## -#if $widget() == "slider" -######################################################################## -$win = Qt.QVBoxLayout() -self._$(id)_label = Qt.QLabel($label) -self._$(id)_slider = Qwt.QwtSlider(None, Qt.$orient, Qwt.QwtSlider.$orient.scalepos, Qwt.QwtSlider.BgSlot) -self._$(id)_slider.setRange($start, $stop, $step) -self._$(id)_slider.setValue(self.$id) -self._$(id)_slider.$(orient.minfcn)($min_len) -self._$(id)_slider.valueChanged.connect(self.set_$(id)) -#if 'horizontal' in $orient().lower() -self._$(id)_label.setAlignment(Qt.Qt.AlignBottom | Qt.Qt.AlignHCenter) -$(win).addWidget(self._$(id)_label) -$(win).addWidget(self._$(id)_slider) -#elif 'vertical' in $orient().lower() -self._$(id)_label.setAlignment(Qt.Qt.AlignTop) -$(win).addWidget(self._$(id)_slider) -$(win).addWidget(self._$(id)_label) -#end if -#end if -######################################################################## -#if $widget() == "counter_slider" -######################################################################## -$win = Qt.QVBoxLayout() -self._$(id)_tool_bar = Qt.QToolBar(self) -$(win).addWidget(self._$(id)_tool_bar) -self._$(id)_tool_bar.addWidget(Qt.QLabel($label+": ")) -class qwt_counter_pyslot(Qwt.QwtCounter): - def __init__(self, parent=None): - Qwt.QwtCounter.__init__(self, parent) - @pyqtSlot('double') - def setValue(self, value): - super(Qwt.QwtCounter, self).setValue(value) -self._$(id)_counter = qwt_counter_pyslot() -self._$(id)_counter.setRange($start, $stop, $step) -self._$(id)_counter.setNumButtons(2) -self._$(id)_counter.setValue(self.$id) -self._$(id)_tool_bar.addWidget(self._$(id)_counter) -self._$(id)_counter.valueChanged.connect(self.set_$(id)) -self._$(id)_slider = Qwt.QwtSlider(None, Qt.Qt.Horizontal, Qwt.QwtSlider.BottomScale, Qwt.QwtSlider.BgSlot) -self._$(id)_slider.setRange($start, $stop, $step) -self._$(id)_slider.setValue(self.$id) -self._$(id)_slider.setMinimumWidth($min_len) -self._$(id)_slider.valueChanged.connect(self.set_$(id)) -$(win).addWidget(self._$(id)_slider) -#end if +range = Range($start, $stop, $step, $value, $min_len) +$(win) = RangeWidget(range, self.set_$(id), $label, "$widget") $(gui_hint()($win))</make> <callback>self.set_$(id)($value)</callback> - <callback>#if $widget() == "knob" -Qt.QMetaObject.invokeMethod(self._$(id)_knob, "setValue", Qt.Q_ARG("double", $id)) -#end if -#if $widget() == "thermo" -Qt.QMetaObject.invokeMethod(self._$(id)_thermo, "setValue", Qt.Q_ARG("double", $id)) -#end if -#if $widget() == "counter" -Qt.QMetaObject.invokeMethod(self._$(id)_counter, "setValue", Qt.Q_ARG("double", $id)) -#end if -#if $widget() == "slider" -Qt.QMetaObject.invokeMethod(self._$(id)_slider, "setValue", Qt.Q_ARG("double", $id)) -#end if -#if $widget() == "counter_slider" -Qt.QMetaObject.invokeMethod(self._$(id)_counter, "setValue", Qt.Q_ARG("double", $id)) -Qt.QMetaObject.invokeMethod(self._$(id)_slider, "setValue", Qt.Q_ARG("double", $id)) -#end if</callback> <param> <name>Label</name> <key>label</key> @@ -172,15 +58,14 @@ Qt.QMetaObject.invokeMethod(self._$(id)_slider, "setValue", Qt.Q_ARG("double", $ <option><name>Counter + Slider</name><key>counter_slider</key></option> <option><name>Counter</name><key>counter</key></option> <option><name>Slider</name><key>slider</key></option> - <option><name>Knob</name><key>knob</key></option> - <option><name>Thermo</name><key>thermo</key></option> + <option><name>Knob</name><key>dial</key></option> </param> <param> <name>Orientation</name> <key>orient</key> <value>Qt.Horizontal</value> <type>enum</type> - <hide>#if $widget() in ("slider", "thermo") then 'part' else 'all'#</hide> + <hide>#if $widget() == "slider" then 'part' else 'all'#</hide> <option> <name>Horizontal</name> <key>Qt.Horizontal</key> @@ -199,8 +84,9 @@ Qt.QMetaObject.invokeMethod(self._$(id)_slider, "setValue", Qt.Q_ARG("double", $ <key>min_len</key> <value>200</value> <type>int</type> - <hide>#if $widget().split('_')[0] in ("slider", "counter", "thermo") then 'part' else 'all'#</hide> + <hide>part</hide> </param> +<!-- from min_len <hide>#if $widget().split('_')[0] in ("slider", "counter") then 'part' else 'all'#</hide>--> <param> <name>GUI Hint</name> <key>gui_hint</key> diff --git a/gr-qtgui/python/qtgui/CMakeLists.txt b/gr-qtgui/python/qtgui/CMakeLists.txt index c3d83f6034..4fa4d0f484 100644 --- a/gr-qtgui/python/qtgui/CMakeLists.txt +++ b/gr-qtgui/python/qtgui/CMakeLists.txt @@ -22,6 +22,7 @@ include(GrPython) GR_PYTHON_INSTALL( FILES __init__.py + range.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/qtgui COMPONENT "qtgui_python" ) diff --git a/gr-qtgui/python/qtgui/__init__.py b/gr-qtgui/python/qtgui/__init__.py index e9aeea7a86..224bde071e 100644 --- a/gr-qtgui/python/qtgui/__init__.py +++ b/gr-qtgui/python/qtgui/__init__.py @@ -26,9 +26,12 @@ Provides a GUI interface using the QT backend. # The presence of this file turns this directory into a Python package import os + try: from qtgui_swig import * except ImportError: dirname, filename = os.path.split(os.path.abspath(__file__)) __path__.append(os.path.join(dirname, "..", "..", "swig")) from qtgui_swig import * + +from range import Range, RangeWidget diff --git a/gr-qtgui/python/qtgui/range.py b/gr-qtgui/python/qtgui/range.py new file mode 100755 index 0000000000..63d64d4543 --- /dev/null +++ b/gr-qtgui/python/qtgui/range.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright 2015 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from PyQt4 import Qt, QtCore, QtGui +import numpy + +class Range(object): + def __init__(self, minv, maxv, step, default, min_length): + self.min = float(minv) + self.max = float(maxv) + self.step = float(step) + self.default = float(default) + self.min_length = min_length + self.find_precision() + self.find_nsteps() + + def find_precision(self): + temp = str(float(self.step)-int(self.step))[2:] + if len(temp) > 13: + self.precision = 15 + else: + self.precision = len(temp)+2 + + def find_nsteps(self): + temp = numpy.arange(self.min,self.max+self.step,self.step) + self.ds_steps = len(temp) + self.ds_vals = (numpy.linspace(self.min,self.max,num=self.ds_steps)).tolist() + +class RangeWidget(QtGui.QWidget): + def __init__(self, ranges, slot, label, style): + """ Creates the QT Range widget """ + QtGui.QWidget.__init__(self) + + self.range = ranges + self.slot = slot + self.style = style + + layout = Qt.QHBoxLayout() + label = Qt.QLabel(label) + layout.addWidget(label) + + if style == "dial": + self.d_widget = self.Dial(self, self.range, self.ds_modified_slot) + elif style == "slider": + self.d_widget = self.Slider(self, self.range, self.ds_modified_slot) + elif style == "counter": + self.d_widget = self.Counter(self, self.range, self.c_modified_slot) + elif style == "counter_slider": + self.d_widget = self.CounterSlider(self, self.range, self.ds_modified_slot, self.c_modified_slot) + else: + self.d_widget = self.CounterSlider(self, self.range, self.ds_modified_slot, self.c_modified_slot) + + layout.addWidget(self.d_widget) + self.setLayout(layout) + + def ds_modified_slot(self,val): + self.slot(self.range.ds_vals[val]) + if self.style == "counter_slider": + self.d_widget.set_counter(self.range.ds_vals[val]) + + def c_modified_slot(self,val): + self.slot(val) + if self.style == "counter_slider": + temp = [abs(x-val) for x in self.range.ds_vals] + self.d_widget.set_slider(temp.index(min(temp))) + + class Dial(QtGui.QDial): + """ Creates the range using a dial """ + def __init__(self, parent, ranges, slot): + QtGui.QDial.__init__(self, parent) + self.setRange(0, ranges.ds_steps-1) + self.setSingleStep(ranges.step) + self.setNotchesVisible(True) + self.setNotchTarget(ranges.step) + self.setValue(ranges.default) + self.valueChanged.connect(slot) + + class Slider(QtGui.QSlider): + """ Creates the range using a slider """ + def __init__(self, parent, ranges, slot): + QtGui.QSlider.__init__(self, QtCore.Qt.Horizontal, parent) + self.setFocusPolicy(QtCore.Qt.NoFocus) + self.setRange(0, ranges.ds_steps-1) + self.setValue(ranges.default) + self.setPageStep(ranges.step) + self.setSingleStep(ranges.step) + self.setTickPosition(1) + self.setTickInterval(ranges.ds_steps) + self.setTracking(False) + self.setInvertedControls(True) + self.valueChanged.connect(slot) + + class Counter(QtGui.QDoubleSpinBox): + """ Creates the range using a counter """ + def __init__(self, parent, ranges, slot): + QtGui.QDoubleSpinBox.__init__(self, parent) + self.setRange(ranges.min, ranges.max) + self.setValue(ranges.default) + self.setSingleStep(ranges.step) + self.setDecimals(ranges.precision) + self.valueChanged.connect(slot) + + class CounterSlider(QtGui.QWidget): + """ Creates the range using a counter and slider """ + def __init__(self, parent, ranges, s_slot, c_slot): + QtGui.QWidget.__init__(self, parent) + + # Need another horizontal layout + layout = Qt.QHBoxLayout() + + # Create a slider with the top-level widget as the parent + self.slider = RangeWidget.Slider(parent,ranges,s_slot) + layout.addWidget(self.slider) + + # Setup the counter + self.counter = RangeWidget.Counter(parent,ranges,c_slot) + layout.addWidget(self.counter) + + # Wire the events to each other + #counter.valueChanged.connect(slider.setValue) + #slider.valueChanged.connect(counter.setValue) + self.counter.valueChanged.connect(c_slot) + self.slider.valueChanged.connect(s_slot) + + self.setLayout(layout) + + def set_slider(self,val): + self.slider.setValue(val) + def set_counter(self,val): + self.counter.setValue(val) + + + + + + + |