Always open console on Windows (but hide it)
Otherwise program crashes when trying to communicate with subprocess (e.g. soapy_power) if started in pythonw.exe, bacause console is missing.
This commit is contained in:
parent
e9391aedc0
commit
9d21d49157
@ -2,4 +2,3 @@ include LICENSE
|
||||
include README.rst
|
||||
include qspectrumanalyzer.desktop
|
||||
include qspectrumanalyzer.png
|
||||
include qspectrumanalyzer.svg
|
||||
|
2
PKGBUILD
2
PKGBUILD
@ -2,7 +2,7 @@
|
||||
pkgname=qspectrumanalyzer
|
||||
pkgver=2.1.0
|
||||
pkgrel=1
|
||||
pkgdesc="Spectrum analyzer for multiple SDR platforms (PyQtGraph based GUI for soapy_power, rx_power, rtl_power, hackrf_sweep and other backends)"
|
||||
pkgdesc="Spectrum analyzer for multiple SDR platforms (PyQtGraph based GUI for soapy_power, rtl_power, hackrf_sweep, rx_power and other backends)"
|
||||
arch=('any')
|
||||
url="https://github.com/xmikos/qspectrumanalyzer"
|
||||
license=('GPL3')
|
||||
|
@ -2,7 +2,7 @@ QSpectrumAnalyzer
|
||||
=================
|
||||
|
||||
Spectrum analyzer for multiple SDR platforms (PyQtGraph based GUI for soapy_power,
|
||||
rx_power, rtl_power, hackrf_sweep and other backends)
|
||||
rtl_power, hackrf_sweep, rx_power and other backends)
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from qspectrumanalyzer.__main__ import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
31
qspectrumanalyzer/__main__.py
Executable file → Normal file
31
qspectrumanalyzer/__main__.py
Executable file → Normal file
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, signal, time
|
||||
import sys, os, signal, time, argparse
|
||||
|
||||
from Qt import QtCore, QtGui, QtWidgets, __binding__
|
||||
|
||||
@ -17,6 +17,8 @@ from qspectrumanalyzer.ui_qspectrumanalyzer_persistence import Ui_QSpectrumAnaly
|
||||
from qspectrumanalyzer.ui_qspectrumanalyzer_colors import Ui_QSpectrumAnalyzerColors
|
||||
from qspectrumanalyzer.ui_qspectrumanalyzer import Ui_QSpectrumAnalyzerMainWindow
|
||||
|
||||
debug = False
|
||||
|
||||
# Allow CTRL+C and/or SIGTERM to kill us (PyQt blocks it otherwise)
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
||||
@ -240,6 +242,10 @@ class QSpectrumAnalyzerMainWindow(QtWidgets.QMainWindow, Ui_QSpectrumAnalyzerMai
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
# Set window icon
|
||||
icon_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "qspectrumanalyzer.svg")
|
||||
self.setWindowIcon(QtGui.QIcon(icon_path))
|
||||
|
||||
# Create plot widgets and update UI
|
||||
self.spectrumPlotWidget = SpectrumPlotWidget(self.mainPlotLayout)
|
||||
self.waterfallPlotWidget = WaterfallPlotWidget(self.waterfallPlotLayout, self.histogramPlotLayout)
|
||||
@ -612,7 +618,28 @@ class QSpectrumAnalyzerMainWindow(QtWidgets.QMainWindow, Ui_QSpectrumAnalyzerMai
|
||||
|
||||
|
||||
def main():
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
global debug
|
||||
|
||||
# Parse command line arguments
|
||||
parser= argparse.ArgumentParser(
|
||||
prog="qspectrumanalyzer",
|
||||
description="Spectrum analyzer for multiple SDR platforms",
|
||||
)
|
||||
parser.add_argument("--debug", action="store_true",
|
||||
help="detailed debugging messages")
|
||||
parser.add_argument("--version", action="version",
|
||||
version="%(prog)s {}".format(__version__))
|
||||
args, unparsed_args = parser.parse_known_args()
|
||||
debug = args.debug
|
||||
|
||||
# Hide console window on Windows
|
||||
if sys.platform == 'win32' and not debug:
|
||||
from qspectrumanalyzer import windows
|
||||
if windows.is_attached_console_visible():
|
||||
windows.set_attached_console_visible(False)
|
||||
|
||||
# Start PyQt application
|
||||
app = QtWidgets.QApplication(sys.argv[:1] + unparsed_args)
|
||||
app.setOrganizationName("QSpectrumAnalyzer")
|
||||
app.setOrganizationDomain("qspectrumanalyzer.eutopia.cz")
|
||||
app.setApplicationName("QSpectrumAnalyzer")
|
||||
|
@ -82,6 +82,7 @@ class BasePowerThread(QtCore.QThread):
|
||||
"""Terminate power process"""
|
||||
with self._shutdown_lock:
|
||||
if self.process:
|
||||
if self.process.poll() is None:
|
||||
try:
|
||||
self.process.terminate()
|
||||
except ProcessLookupError:
|
||||
|
@ -140,6 +140,7 @@ class PowerThread(BasePowerThread):
|
||||
"""Stop soapy_power process"""
|
||||
with self._shutdown_lock:
|
||||
if self.process:
|
||||
if self.process.poll() is None:
|
||||
try:
|
||||
if sys.platform == 'win32':
|
||||
self.process.send_signal(signal.CTRL_BREAK_EVENT)
|
||||
|
133
qspectrumanalyzer/qspectrumanalyzer.svg
Normal file
133
qspectrumanalyzer/qspectrumanalyzer.svg
Normal file
@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="32"
|
||||
id="svg4290"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
viewBox="0 0 32 32"
|
||||
inkscape:export-filename="qspectrumanalyzer.png"
|
||||
inkscape:export-xdpi="135"
|
||||
inkscape:export-ydpi="135"
|
||||
sodipodi:docname="qspectrumanalyzer.svg">
|
||||
<defs
|
||||
id="defs4292" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="5.6568543"
|
||||
inkscape:cx="0.51171273"
|
||||
inkscape:cy="17.429759"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:document-units="px"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-bbox="false"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="709"
|
||||
inkscape:window-x="-4"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4298" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata4295">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<rect
|
||||
style="fill:#000000;stroke:#666666;stroke-opacity:1"
|
||||
id="rect4300"
|
||||
width="30"
|
||||
height="30"
|
||||
x="1"
|
||||
y="1"
|
||||
rx="3"
|
||||
ry="3" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#666666;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 16,1 0,30"
|
||||
id="path4302"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#666666;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 31,16 1,16"
|
||||
id="path4302-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4302"
|
||||
id="use4369"
|
||||
transform="translate(-7.5,0)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4302"
|
||||
id="use4371"
|
||||
transform="translate(7.5,0)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4373"
|
||||
d="M 31,8.5 1,8.5"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#666666;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<use
|
||||
x="0"
|
||||
y="0"
|
||||
xlink:href="#path4302-5"
|
||||
id="use4375"
|
||||
transform="translate(0,7.5)"
|
||||
width="100%"
|
||||
height="100%" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#00ff00;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 1.0625,25.25 c 0,0 2.5545099,5.432144 4.3470654,0.903939 0.6415968,-1.620748 1.1843693,-10.505075 2.3294368,-10.451145 1.124605,0.05297 1.2928473,9.79388 3.0231028,11.399454 0.836834,0.735662 2.019611,-2.789575 2.96484,-2.691821 1.178304,0.121857 2.125956,3.657855 3.181223,2.383073 2.07617,-2.508052 1.527752,-21.6078848 2.588897,-21.5746877 1.200441,0.037555 1.333727,19.4989257 3.765313,21.7522057 1.533625,1.421166 1.791478,-2.106359 3.115303,-2.461012 0.660576,-0.176968 2.034012,3.420657 2.702589,3.52241 0.772278,0.117536 1.624099,-1.153766 2.01348,-0.813666"
|
||||
id="path4394"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="csscssssssc" />
|
||||
<rect
|
||||
style="fill:none;stroke:#666666;stroke-opacity:1"
|
||||
id="rect4300-8"
|
||||
width="30"
|
||||
height="30"
|
||||
x="1"
|
||||
y="1"
|
||||
rx="3"
|
||||
ry="3" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
48
qspectrumanalyzer/windows.py
Normal file
48
qspectrumanalyzer/windows.py
Normal file
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright © Spyder Project Contributors
|
||||
# Licensed under the terms of the MIT License
|
||||
# (see spyder/__init__.py for details)
|
||||
|
||||
"""Windows-specific utilities"""
|
||||
|
||||
|
||||
from ctypes import windll
|
||||
|
||||
|
||||
# --- Window control ---
|
||||
|
||||
SW_SHOW = 5 # activate and display
|
||||
SW_SHOWNA = 8 # show without activation
|
||||
SW_HIDE = 0
|
||||
|
||||
GetConsoleWindow = windll.kernel32.GetConsoleWindow
|
||||
ShowWindow = windll.user32.ShowWindow
|
||||
IsWindowVisible = windll.user32.IsWindowVisible
|
||||
|
||||
# Handle to console window associated with current Python
|
||||
# interpreter procss, 0 if there is no window
|
||||
console_window_handle = GetConsoleWindow()
|
||||
|
||||
def set_attached_console_visible(state):
|
||||
"""Show/hide system console window attached to current process.
|
||||
Return it's previous state.
|
||||
|
||||
Availability: Windows"""
|
||||
flag = {True: SW_SHOW, False: SW_HIDE}
|
||||
return bool(ShowWindow(console_window_handle, flag[state]))
|
||||
|
||||
def is_attached_console_visible():
|
||||
"""Return True if attached console window is visible"""
|
||||
return IsWindowVisible(console_window_handle)
|
||||
|
||||
def set_windows_appusermodelid():
|
||||
"""Make sure correct icon is used on Windows 7 taskbar"""
|
||||
try:
|
||||
return windll.shell32.SetCurrentProcessExplicitAppUserModelID("spyder.Spyder")
|
||||
except AttributeError:
|
||||
return "SetCurrentProcessExplicitAppUserModelID not found"
|
||||
|
||||
|
||||
# [ ] the console state asks for a storage container
|
||||
# [ ] reopen console on exit - better die open than become a zombie
|
33
setup.py
33
setup.py
@ -27,7 +27,7 @@ try:
|
||||
setup_entry_points = {
|
||||
"console_scripts": [
|
||||
Executable('QSpectrumAnalyzer=qspectrumanalyzer.__main__:main',
|
||||
console=False, icon_file='qspectrumanalyzer.ico'),
|
||||
console=True, icon_file='qspectrumanalyzer.ico'),
|
||||
Executable('soapy_power=soapypower.__main__:main',
|
||||
console=True),
|
||||
],
|
||||
@ -39,7 +39,8 @@ except ImportError:
|
||||
setup(
|
||||
name="QSpectrumAnalyzer",
|
||||
version=__version__,
|
||||
description="Spectrum analyzer for multiple SDR platforms (PyQtGraph based GUI for soapy_power, rx_power, rtl_power, hackrf_sweep and other backends)",
|
||||
description=("Spectrum analyzer for multiple SDR platforms "
|
||||
"(PyQtGraph based GUI for soapy_power, rtl_power, hackrf_sweep, rx_power and other backends)"),
|
||||
long_description=open('README.rst').read(),
|
||||
author="Michal Krenek (Mikos)",
|
||||
author_email="m.krenek@gmail.com",
|
||||
@ -48,19 +49,20 @@ setup(
|
||||
packages=["qspectrumanalyzer", "qspectrumanalyzer.backends"],
|
||||
package_data={
|
||||
"qspectrumanalyzer": [
|
||||
"qspectrumanalyzer.svg",
|
||||
"*.ui",
|
||||
"languages/*.qm",
|
||||
"languages/*.ts"
|
||||
]
|
||||
"languages/*.ts",
|
||||
],
|
||||
},
|
||||
data_files=[
|
||||
("share/applications", ["qspectrumanalyzer.desktop"]),
|
||||
("share/pixmaps", ["qspectrumanalyzer.png"])
|
||||
("share/pixmaps", ["qspectrumanalyzer.png"]),
|
||||
],
|
||||
install_requires=[
|
||||
"soapy_power>=1.5.0",
|
||||
"soapy_power>=1.6.0",
|
||||
"pyqtgraph>=0.10.0",
|
||||
"Qt.py"
|
||||
"Qt.py",
|
||||
],
|
||||
classifiers=[
|
||||
"Development Status :: 4 - Beta",
|
||||
@ -75,17 +77,26 @@ setup(
|
||||
"Operating System :: OS Independent",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Topic :: Communications :: Ham Radio",
|
||||
"Topic :: Scientific/Engineering :: Visualization"
|
||||
"Topic :: Scientific/Engineering :: Visualization",
|
||||
],
|
||||
options={
|
||||
'build_qt': {
|
||||
'packages': ['qspectrumanalyzer'],
|
||||
'languages': ['cs'],
|
||||
'replacement_bindings': 'Qt'
|
||||
'replacement_bindings': 'Qt',
|
||||
},
|
||||
'build_exe': {
|
||||
'datas': [
|
||||
('qspectrumanalyzer/qspectrumanalyzer.svg', 'qspectrumanalyzer'),
|
||||
('qspectrumanalyzer/*.ui', 'qspectrumanalyzer'),
|
||||
('qspectrumanalyzer/languages/*.ts', 'qspectrumanalyzer/languages'),
|
||||
('qspectrumanalyzer/languages/*.qm', 'qspectrumanalyzer/languages'),
|
||||
('README.rst', '.'),
|
||||
('LICENSE', '.'),
|
||||
],
|
||||
},
|
||||
'build_exe': {},
|
||||
'bdist_msi': {
|
||||
'upgrade_code': '30740ef4-84e7-4e67-8e4a-12b53492c387',
|
||||
'upgrade_code': '{30740EF4-84E7-4E67-8E4A-12B53492C387}',
|
||||
'shortcuts': [
|
||||
'ProgramMenuFolder\\QSpectrumAnalyzer=QSpectrumAnalyzer',
|
||||
],
|
||||
|
@ -1,5 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
from soapypower.__main__ import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue
Block a user