From 98cf134cca637d1c9c4fc2d079b8fb10d2f3aa5e Mon Sep 17 00:00:00 2001
From: tangchao0503 <735056338@qq.com>
Date: Tue, 6 Sep 2022 22:54:14 +0800
Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E6=AC=A1=E6=8F=90=E4=BA=A4?=
=?UTF-8?q?=201=E3=80=81hpi=E7=9A=84=E5=8F=AF=E7=94=A8=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=EF=BC=9B=202=E3=80=81=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=A4=9A?=
=?UTF-8?q?=E6=AC=A1=E7=82=B9=E5=87=BB=E6=9B=9D=E5=85=89=E5=90=8E=EF=BC=8C?=
=?UTF-8?q?=E7=A6=8F=E4=BA=AE=E5=BA=A6=E6=95=B0=E6=8D=AE=E9=94=99=E8=AF=AF?=
=?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=203=E3=80=81=E5=AE=9A?=
=?UTF-8?q?=E6=A0=87=E6=96=B9=E5=BC=8F=E4=B8=BA=E5=A4=A7=E7=9A=84=E8=93=9D?=
=?UTF-8?q?=E8=8F=B2=E7=A7=AF=E5=88=86=E7=90=83=E7=9A=84=E6=A0=87=E5=87=86?=
=?UTF-8?q?=E8=83=BD=E9=87=8F=E6=9B=B2=E7=BA=BF=EF=BC=8C=E8=80=8C=E4=B8=8D?=
=?UTF-8?q?=E6=98=AF=E5=9F=BA=E4=BA=8Easd=E7=9A=84=E8=83=BD=E9=87=8F?=
=?UTF-8?q?=E6=9B=B2=E7=BA=BF=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 258 ++
0.1remove dark noise.py | 117 +
0.2stretch.py | 141 +
corning_config.ini | 15 +
delete.py | 23 +
library/__init__.py | 0
library/config.py | 514 ++++
library/dir_manager.py | 29 +
library/functions.py | 144 +
library/image_reader_writer.py | 40 +
library/log.py | 50 +
library/log/corning_config.ini | 25 +
library/matplotlib_display_image_spectral.py | 161 ++
library/message_box.py | 53 +
library/message_box_ui.py | 90 +
library/message_box_ui.ui | 106 +
library/multithread.py | 81 +
pyqt_multithread.py | 143 +
record_system_v11/1record_system_v1.1.py | 230 ++
record_system_v12/1record_system_v1.2.py | 142 +
record_system_v13/1record_system_v1.3.py | 158 ++
record_system_v21/2record_system_v2.1.py | 569 ++++
record_system_v21/arcus_control_ui.py | 48 +
record_system_v21/arcus_control_ui.ui | 81 +
record_system_v21/enter_window.py | 47 +
record_system_v21/enter_window.ui | 73 +
record_system_v21/image_Window.py | 231 ++
record_system_v21/image_Window.ui | 377 +++
record_system_v21/spectral_Window.py | 94 +
record_system_v21/spectral_Window.ui | 180 ++
record_system_v22/2record_system_v2.2.py | 1203 +++++++++
record_system_v22/arcus_control_ui.py | 48 +
record_system_v22/arcus_control_ui.ui | 81 +
record_system_v22/enter_window.py | 47 +
record_system_v22/enter_window.ui | 73 +
record_system_v22/image_Window.py | 231 ++
record_system_v22/image_Window.ui | 377 +++
record_system_v22/spectral_Window.py | 94 +
record_system_v22/spectral_Window.ui | 180 ++
record_system_v23/2record_system_v2.3.py | 1438 ++++++++++
record_system_v23/arcus_control_ui.py | 48 +
record_system_v23/arcus_control_ui.ui | 81 +
record_system_v23/enter_window.py | 47 +
record_system_v23/enter_window.ui | 73 +
record_system_v23/image_Window.py | 231 ++
record_system_v23/image_Window.ui | 377 +++
record_system_v23/spectral_Window.py | 94 +
record_system_v23/spectral_Window.ui | 180 ++
record_system_v24/2record_system_v24.py | 1828 +++++++++++++
record_system_v24/ArcusDevice.py | 75 +
record_system_v24/corning_config.ini | 23 +
record_system_v24/delete.py | 42 +
record_system_v24/ui/__init__.py | 0
record_system_v24/ui/arcus_control_ui.py | 48 +
record_system_v24/ui/arcus_control_ui.ui | 81 +
record_system_v24/ui/enter_window.py | 47 +
record_system_v24/ui/enter_window.ui | 73 +
record_system_v24/ui/image_Window.py | 246 ++
record_system_v24/ui/image_Window.ui | 405 +++
record_system_v24/ui/spectral_Window.py | 104 +
record_system_v24/ui/spectral_Window.ui | 212 ++
record_system_v25/2record_system_v25.py | 1801 +++++++++++++
record_system_v25/delete.py | 3 +
record_system_v25/log/corning_config.ini | 23 +
record_system_v25/ui/__init__.py | 0
record_system_v25/ui/arcus_control_ui.py | 48 +
record_system_v25/ui/arcus_control_ui.ui | 81 +
record_system_v25/ui/enter_window.py | 47 +
record_system_v25/ui/enter_window.ui | 73 +
record_system_v25/ui/image_Window.py | 268 ++
record_system_v25/ui/image_Window.ui | 468 ++++
record_system_v25/ui/image_Window_phone.ui | 1083 ++++++++
record_system_v25/ui/spectral_Window.py | 104 +
record_system_v25/ui/spectral_Window.ui | 215 ++
record_system_v25/ui/spectral_Window_phone.ui | 377 +++
record_system_v26/2record_system_v26.py | 2215 ++++++++++++++++
record_system_v26/log/corning_config.ini | 27 +
record_system_v26/ui/__init__.py | 0
record_system_v26/ui/enter_window.py | 150 ++
record_system_v26/ui/enter_window.ui | 178 ++
record_system_v26/ui/image_Window_phone.py | 830 ++++++
record_system_v26/ui/image_Window_phone.ui | 1323 ++++++++++
record_system_v26/ui/spectral_Window_phone.py | 629 +++++
record_system_v26/ui/spectral_Window_phone.ui | 1057 ++++++++
record_system_v27/2record_system_v27.py | 2304 ++++++++++++++++
record_system_v27/log/corning_config.ini | 27 +
record_system_v27/ui/__init__.py | 0
record_system_v27/ui/enter_window.py | 150 ++
record_system_v27/ui/enter_window.ui | 178 ++
.../ui/image_Window_phone - 副本 (2).ui | 1358 ++++++++++
record_system_v27/ui/image_Window_phone.py | 868 +++++++
record_system_v27/ui/image_Window_phone.ui | 1395 ++++++++++
record_system_v27/ui/spectral_Window_phone.py | 629 +++++
record_system_v27/ui/spectral_Window_phone.ui | 1057 ++++++++
record_system_v28/2record_system_v28.py | 2313 +++++++++++++++++
record_system_v28/delete.py | 63 +
.../log/corning_config - 20220627.ini | 48 +
record_system_v28/log/corning_config.ini | 48 +
record_system_v28/ui/__init__.py | 0
record_system_v28/ui/enter_window.py | 150 ++
record_system_v28/ui/enter_window.ui | 178 ++
.../ui/image_Window_phone - 副本 (2).ui | 1358 ++++++++++
record_system_v28/ui/image_Window_phone.py | 868 +++++++
record_system_v28/ui/image_Window_phone.ui | 1395 ++++++++++
record_system_v28/ui/spectral_Window_phone.py | 635 +++++
record_system_v28/ui/spectral_Window_phone.ui | 1071 ++++++++
106 files changed, 39400 insertions(+)
create mode 100644 .gitignore
create mode 100644 0.1remove dark noise.py
create mode 100644 0.2stretch.py
create mode 100644 corning_config.ini
create mode 100644 delete.py
create mode 100644 library/__init__.py
create mode 100644 library/config.py
create mode 100644 library/dir_manager.py
create mode 100644 library/functions.py
create mode 100644 library/image_reader_writer.py
create mode 100644 library/log.py
create mode 100644 library/log/corning_config.ini
create mode 100644 library/matplotlib_display_image_spectral.py
create mode 100644 library/message_box.py
create mode 100644 library/message_box_ui.py
create mode 100644 library/message_box_ui.ui
create mode 100644 library/multithread.py
create mode 100644 pyqt_multithread.py
create mode 100644 record_system_v11/1record_system_v1.1.py
create mode 100644 record_system_v12/1record_system_v1.2.py
create mode 100644 record_system_v13/1record_system_v1.3.py
create mode 100644 record_system_v21/2record_system_v2.1.py
create mode 100644 record_system_v21/arcus_control_ui.py
create mode 100644 record_system_v21/arcus_control_ui.ui
create mode 100644 record_system_v21/enter_window.py
create mode 100644 record_system_v21/enter_window.ui
create mode 100644 record_system_v21/image_Window.py
create mode 100644 record_system_v21/image_Window.ui
create mode 100644 record_system_v21/spectral_Window.py
create mode 100644 record_system_v21/spectral_Window.ui
create mode 100644 record_system_v22/2record_system_v2.2.py
create mode 100644 record_system_v22/arcus_control_ui.py
create mode 100644 record_system_v22/arcus_control_ui.ui
create mode 100644 record_system_v22/enter_window.py
create mode 100644 record_system_v22/enter_window.ui
create mode 100644 record_system_v22/image_Window.py
create mode 100644 record_system_v22/image_Window.ui
create mode 100644 record_system_v22/spectral_Window.py
create mode 100644 record_system_v22/spectral_Window.ui
create mode 100644 record_system_v23/2record_system_v2.3.py
create mode 100644 record_system_v23/arcus_control_ui.py
create mode 100644 record_system_v23/arcus_control_ui.ui
create mode 100644 record_system_v23/enter_window.py
create mode 100644 record_system_v23/enter_window.ui
create mode 100644 record_system_v23/image_Window.py
create mode 100644 record_system_v23/image_Window.ui
create mode 100644 record_system_v23/spectral_Window.py
create mode 100644 record_system_v23/spectral_Window.ui
create mode 100644 record_system_v24/2record_system_v24.py
create mode 100644 record_system_v24/ArcusDevice.py
create mode 100644 record_system_v24/corning_config.ini
create mode 100644 record_system_v24/delete.py
create mode 100644 record_system_v24/ui/__init__.py
create mode 100644 record_system_v24/ui/arcus_control_ui.py
create mode 100644 record_system_v24/ui/arcus_control_ui.ui
create mode 100644 record_system_v24/ui/enter_window.py
create mode 100644 record_system_v24/ui/enter_window.ui
create mode 100644 record_system_v24/ui/image_Window.py
create mode 100644 record_system_v24/ui/image_Window.ui
create mode 100644 record_system_v24/ui/spectral_Window.py
create mode 100644 record_system_v24/ui/spectral_Window.ui
create mode 100644 record_system_v25/2record_system_v25.py
create mode 100644 record_system_v25/delete.py
create mode 100644 record_system_v25/log/corning_config.ini
create mode 100644 record_system_v25/ui/__init__.py
create mode 100644 record_system_v25/ui/arcus_control_ui.py
create mode 100644 record_system_v25/ui/arcus_control_ui.ui
create mode 100644 record_system_v25/ui/enter_window.py
create mode 100644 record_system_v25/ui/enter_window.ui
create mode 100644 record_system_v25/ui/image_Window.py
create mode 100644 record_system_v25/ui/image_Window.ui
create mode 100644 record_system_v25/ui/image_Window_phone.ui
create mode 100644 record_system_v25/ui/spectral_Window.py
create mode 100644 record_system_v25/ui/spectral_Window.ui
create mode 100644 record_system_v25/ui/spectral_Window_phone.ui
create mode 100644 record_system_v26/2record_system_v26.py
create mode 100644 record_system_v26/log/corning_config.ini
create mode 100644 record_system_v26/ui/__init__.py
create mode 100644 record_system_v26/ui/enter_window.py
create mode 100644 record_system_v26/ui/enter_window.ui
create mode 100644 record_system_v26/ui/image_Window_phone.py
create mode 100644 record_system_v26/ui/image_Window_phone.ui
create mode 100644 record_system_v26/ui/spectral_Window_phone.py
create mode 100644 record_system_v26/ui/spectral_Window_phone.ui
create mode 100644 record_system_v27/2record_system_v27.py
create mode 100644 record_system_v27/log/corning_config.ini
create mode 100644 record_system_v27/ui/__init__.py
create mode 100644 record_system_v27/ui/enter_window.py
create mode 100644 record_system_v27/ui/enter_window.ui
create mode 100644 record_system_v27/ui/image_Window_phone - 副本 (2).ui
create mode 100644 record_system_v27/ui/image_Window_phone.py
create mode 100644 record_system_v27/ui/image_Window_phone.ui
create mode 100644 record_system_v27/ui/spectral_Window_phone.py
create mode 100644 record_system_v27/ui/spectral_Window_phone.ui
create mode 100644 record_system_v28/2record_system_v28.py
create mode 100644 record_system_v28/delete.py
create mode 100644 record_system_v28/log/corning_config - 20220627.ini
create mode 100644 record_system_v28/log/corning_config.ini
create mode 100644 record_system_v28/ui/__init__.py
create mode 100644 record_system_v28/ui/enter_window.py
create mode 100644 record_system_v28/ui/enter_window.ui
create mode 100644 record_system_v28/ui/image_Window_phone - 副本 (2).ui
create mode 100644 record_system_v28/ui/image_Window_phone.py
create mode 100644 record_system_v28/ui/image_Window_phone.ui
create mode 100644 record_system_v28/ui/spectral_Window_phone.py
create mode 100644 record_system_v28/ui/spectral_Window_phone.ui
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1245444
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,258 @@
+# tc
+/0/*
+/problem880_960/*
+/installer/*
+/test/*
+*.hdr
+*.enp
+*.log # 自己写的log文件
+/.idea
+20220627
+20220628
+20220628_focus
+20220629_focus
+corning410_test
+corning410_test.hdr
+data
+
+
+
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+# This is especially recommended for binary packages to ensure reproducibility, and is more
+# commonly ignored for libraries.
+# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+# in version control.
+# https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+# and can be added to the global gitignore or merged into this file. For a more nuclear
+# option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
+
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
diff --git a/0.1remove dark noise.py b/0.1remove dark noise.py
new file mode 100644
index 0000000..600cfb4
--- /dev/null
+++ b/0.1remove dark noise.py
@@ -0,0 +1,117 @@
+'''
+1、读取影像
+2、bin
+3、去除暗电流 + 转反射率
+4、保存光谱
+'''
+import numpy as np
+import matplotlib.pyplot as plt
+import sys
+from osgeo import gdal #读写影像数据
+
+class GRID:
+
+ #读图像文件
+ @classmethod
+ def read_img(cls, filename):
+ try:
+ dataset = gdal.Open(filename) # 打开文件
+ im_width = dataset.RasterXSize # 栅格矩阵的列数
+ im_height = dataset.RasterYSize # 栅格矩阵的行数
+ num_bands = dataset.RasterCount # 栅格矩阵的波段数
+ im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
+ im_proj = dataset.GetProjection() # 地图投影信息
+ im_data = dataset.ReadAsArray(0, 0, im_width, im_height) # 将数据写成数组,对应栅格矩阵
+ del dataset
+ return im_proj, im_geotrans, im_data
+ except:
+ sys.exit()
+
+ #写文件,以写成tif为例
+ @classmethod
+ def write_img(cls, dst_filename, data):
+ format = "ENVI"
+ driver = gdal.GetDriverByName(format)
+ RasterXSize = data.shape[2] # 遥感影像的sample(列数)
+ RasterYSize = data.shape[1] # 遥感影像的line(行数)
+ band = data.shape[0]
+ dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize,
+ band,
+ gdal.GDT_Float32) # driver.Create()函数中RasterXSize代表影像的sample(列数),RasterYSize代表影像的line(行数)
+ for i in range(band):
+ dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始,所以dst_ds.GetRasterBand(i+1)
+ dst_ds = None
+
+ # bin
+ @classmethod
+ def bin(cls, img, nBin):
+ if nBin == 1:
+ return img
+ image_bin = np.empty((int(img.shape[0] / nBin), img.shape[1], img.shape[2]))
+ k = np.arange(img.shape[0])[0::nBin]
+ for i in range(image_bin.shape[0]):
+ for j in range(nBin):
+ image_bin[i] += img[k[i] + j]
+ return image_bin
+
+# 文件名
+image = r'D:\py_program\corning410\test_spectral\lib_spectral2_20帧\delete\leaf'
+dark_image = r'D:\py_program\corning410\test_spectral\lib_spectral2_20帧\delete\dark'
+baiban_image = r'D:\py_program\corning410\test_spectral\lib_spectral2_20帧\delete\baiban'
+
+# 读取影像
+print('读取影像')
+im_proj, im_geotrans, im_data = GRID.read_img(image)
+d1, d2, dark_noise = GRID.read_img(dark_image)
+b1, b2, baiban = GRID.read_img(baiban_image)
+
+
+
+n_bin = 1
+im_data = GRID.bin(im_data, n_bin)
+dark_noise = GRID.bin(dark_noise, n_bin)
+baiban = GRID.bin(baiban, n_bin)
+
+
+# (1)去除暗电流;(2)转反射率
+dark_noise_mean = dark_noise.mean(axis=1)
+baiban_mean = baiban.mean(axis=1)
+im_data = im_data.astype(np.float)
+for i in range(im_data.shape[1]):
+ im_data[:, i, :] = (im_data[:, i, :] - dark_noise_mean).astype(np.float) / baiban_mean.astype(np.float)
+
+
+print('将影像写入到文件')
+GRID.write_img(image + '_reflectivity', im_data)
+
+
+# 计算波长
+def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+wavelength_tmp = np.empty(300)
+for i in range(340, 640):
+ wavelength_tmp[i - 340] = calculate_wavelength(i)
+wavelength = np.empty(im_data.shape[0])
+k = np.arange(300)[0::n_bin]
+for i in range(wavelength.shape[0]):
+ tmp = 0
+ for j in range(n_bin):
+ tmp += wavelength_tmp[k[i] + j]
+ wavelength[i] = tmp / n_bin
+
+
+
+
+# 保存光谱为txt文件
+spectralNumber = 1
+spectral_container = np.empty((im_data.shape[0], spectralNumber)).astype(np.float)
+spectral_container = np.insert(spectral_container, 0, wavelength, axis=1)
+
+
+spectral = im_data.mean(1).mean(1)
+spectral_container = np.insert(spectral_container, 1, spectral, axis=1)
+np.savetxt(r'D:\py_program\corning410\test_spectral\lib_spectral2_20帧\delete\spectral.txt', spectral_container[:, [0, 1]], fmt='%f')
+
+plt.plot(wavelength, spectral)
+plt.show()
diff --git a/0.2stretch.py b/0.2stretch.py
new file mode 100644
index 0000000..d9e49cc
--- /dev/null
+++ b/0.2stretch.py
@@ -0,0 +1,141 @@
+'''
+1、读取影像
+2、bin
+3、去除暗电流 + 转反射率
+4、保存光谱
+'''
+import numpy as np
+import matplotlib.pyplot as plt
+import sys
+from osgeo import gdal #读写影像数据
+from PIL import Image
+import cv2
+
+
+class GRID:
+
+ #读图像文件
+ @classmethod
+ def read_img(cls, filename):
+ try:
+ dataset = gdal.Open(filename) # 打开文件
+ im_width = dataset.RasterXSize # 栅格矩阵的列数
+ im_height = dataset.RasterYSize # 栅格矩阵的行数
+ num_bands = dataset.RasterCount # 栅格矩阵的波段数
+ im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
+ im_proj = dataset.GetProjection() # 地图投影信息
+ im_data = dataset.ReadAsArray(0, 0, im_width, im_height) # 将数据写成数组,对应栅格矩阵
+ del dataset
+ return im_proj, im_geotrans, im_data
+ except:
+ sys.exit()
+
+ #写文件,以写成tif为例
+ @classmethod
+ def write_img(cls, dst_filename, data):
+ format = "ENVI"
+ driver = gdal.GetDriverByName(format)
+ RasterXSize = data.shape[2] # 遥感影像的sample(列数)
+ RasterYSize = data.shape[1] # 遥感影像的line(行数)
+ band = data.shape[0]
+ dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize,
+ band,
+ gdal.GDT_Float32) # driver.Create()函数中RasterXSize代表影像的sample(列数),RasterYSize代表影像的line(行数)
+ for i in range(band):
+ dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始,所以dst_ds.GetRasterBand(i+1)
+ dst_ds = None
+
+ # bin
+ @classmethod
+ def bin(cls, img, nBin):
+ if nBin == 1:
+ return img
+ image_bin = np.empty((int(img.shape[0] / nBin), img.shape[1], img.shape[2]))
+ k = np.arange(img.shape[0])[0::nBin]
+ for i in range(image_bin.shape[0]):
+ for j in range(nBin):
+ image_bin[i] += img[k[i] + j]
+ return image_bin
+
+ # 计算波长
+ @classmethod
+ def calculate_wavelength(cls, x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+
+wavelength = np.empty(639 - 339)
+for i in range(339, 639):
+ wavelength[i - 339] = GRID.calculate_wavelength(i)
+
+
+# 等效于ENVI拉伸:No stretch
+def stretch(img, minimum=0, maximum=255):
+ if len(img.shape) == 2:
+ img_new = (img - minimum) / (maximum - minimum)
+ img_new[img_new < 0] = 0
+ img_new[img_new > 1] = 1
+ return img_new
+ else:
+ img_new = np.empty(img.shape)
+ for i in range(img.shape[2]):
+ img_new[:, :, i] = (img[:, :, i] - minimum) / (maximum - minimum)
+ img_new[:, :, i][img_new[:, :, i] < 0] = 0
+ img_new[:, :, i][img_new[:, :, i] > 1] = 1
+ return img_new
+
+
+# 当lowPercentile=0, highPercentile=100时,等效于Min-Max Stretching
+# lowPercentile=2, highPercentile=98时,等效于ENVI拉伸:Linear 2%
+# https://blog.csdn.net/LEILEI18A/article/details/80180483
+def percentile_stretching(img, lowPercentile=0, highPercentile=100, minout=0, maxout=255):
+ if len(img.shape) == 2:
+ low = np.percentile(img, lowPercentile)
+ up = np.percentile(img, highPercentile)
+
+ img_new = ((img - low) / (up - low)) * (maxout - minout) + minout
+ img_new[img_new < minout] = minout
+ img_new[img_new > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+ else: # 对于彩色照片,需要先单独对每个波段拉伸
+ img_new = np.empty(img.shape)
+ for i in range(img.shape[2]):
+ low = np.percentile(img[:, :, i], lowPercentile)
+ up = np.percentile(img[:, :, i], highPercentile)
+
+ img_new[:, :, i] = minout + ((img[:, :, i] - low) / (up - low)) * (maxout - minout)
+ img_new[:, :, i][img_new[:, :, i] < minout] = minout
+ img_new[:, :, i][img_new[:, :, i] > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+
+
+# 画出图像直方图
+# https://blog.csdn.net/fly_wt/article/details/83904207
+def image_hist(image): # 画三通道图像的直方图
+ color = ("blue", "green", "red") # 画笔颜色的值可以为大写或小写或只写首字母或大小写混合
+ for i, color in enumerate(color):
+ hist = cv2.calcHist([image], [i], None, [256], [0, 256])
+ plt.plot(hist, color=color)
+ plt.xlim([0, 256])
+ plt.show()
+
+
+print("读取影像")
+#image = r'D:\py_program\corning410\2%拉伸显示问题 + 漏帧\x270\dn值\corning410_test10'
+image = r'D:\corning410_test10'
+im_proj, im_geotrans, im_data = GRID.read_img(image)
+
+
+print("挑取波段用于真彩色显示")
+rgb_raw = np.dstack((im_data[121], im_data[76], im_data[36]))
+rgb = rgb_raw.astype(np.uint8)
+
+
+x1 = stretch(rgb_raw) #等效于ENVI拉伸:No stretch
+x2 = percentile_stretching(rgb_raw) # Min-Max Stretching
+x3 = percentile_stretching(rgb_raw, 2, 98) # 2% Stretching
+
+print("画出影像")
+plt.imshow(x3)
+plt.show()
diff --git a/corning_config.ini b/corning_config.ini
new file mode 100644
index 0000000..399ca2f
--- /dev/null
+++ b/corning_config.ini
@@ -0,0 +1,15 @@
+[basic]
+binning = 1
+default_dir = D:\py_program\corning410
+default_file_name = test
+
+[effective_window]
+start_column_binning_1 = 12
+end_column_binning_1 = 1376
+start_row_binning_1 = 1
+end_row_binning_1 = 300
+start_column_binning_2 = 13
+end_column_binning_2 = 695
+start_row_binning_2 = 1
+end_row_binning_2 = 150
+
diff --git a/delete.py b/delete.py
new file mode 100644
index 0000000..1b3968e
--- /dev/null
+++ b/delete.py
@@ -0,0 +1,23 @@
+def add(x, y):
+ return x+y
+
+class A():
+ x = add(3,4)
+
+
+ def p(self):
+ print(self.x)
+
+
+class B(A):
+ pass
+
+
+
+
+class Dog:
+ tricks = [] # mistaken use of a class variable
+ def __init__(self, name):
+ self.name = name
+ def add_trick(self, trick):
+ self.tricks.append(trick)
diff --git a/library/__init__.py b/library/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/library/config.py b/library/config.py
new file mode 100644
index 0000000..7251636
--- /dev/null
+++ b/library/config.py
@@ -0,0 +1,514 @@
+# 标准库
+import traceback, os
+
+# 三方库
+import configparser
+from PyQt5.QtCore import QObject, pyqtSignal
+
+# 自己写的库
+from library.dir_manager import DirManager
+
+
+# class ConfigFile():
+# def __init__(self):
+# self.base_dir = get_path()
+#
+# self.log_dir = self.base_dir + '//log'
+# self.create_directory(self.log_dir)
+#
+# self.corning_config_file = self.log_dir + '//corning_config.ini'
+#
+# self.read_config_file()
+#
+# self.signals = WorkerSignals()
+# self.signals.image_signal.connect(self.image_record_param_changed)
+# self.signals.spectral_signal.connect(self.spectral_record_param_changed)
+#
+#
+# # 查看是否存在保存光谱和影像文件的目录,如果没有就创建
+# def create_directory(self, directory):
+# if not os.path.exists(directory):
+# print('创建文件夹:', directory)
+# os.makedirs(directory)
+#
+# # 读取配置文件,如果没有就创建
+# def read_config_file(self):
+# if os.path.exists(self.corning_config_file):
+# '''
+# 如果存在配置文件,就从配置文件中读取软件配置信息
+# '''
+# print('配置文件存在!')
+#
+# config = configparser.ConfigParser()
+# config.read(self.corning_config_file)
+#
+# self.image_dir = config.get('image_record_param', 'image_dir')
+# self.create_directory(self.image_dir)
+# self.default_image_name = config.get('image_record_param', 'default_image_name')
+# self.framerate = int(config.get('image_record_param', 'framerate'))
+# self.exposure_time = int(config.get('image_record_param', 'exposure_time'))
+# self.gain = int(float(config.get('image_record_param', 'gain')))
+# self.frame_number = int(config.get('image_record_param', 'frame_number'))
+#
+# self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
+# self.create_directory(self.spectral_dir)
+# self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
+#
+# self.binning = int(config.get('bin', 'binning'))
+# if self.binning == 1:
+# self.start_column = int(config.get('bin', 'start_column_binning_1'))
+# self.end_column = int(config.get('bin', 'end_column_binning_1'))
+# self.start_row = int(config.get('bin', 'start_row_binning_1'))
+# self.end_row = int(config.get('bin', 'end_row_binning_1'))
+# elif self.binning == 2:
+# self.start_column = int(config.get('bin', 'start_column_binning_2'))
+# self.end_column = int(config.get('bin', 'end_column_binning_2'))
+# self.start_row = int(config.get('bin', 'start_row_binning_2'))
+# self.end_row = int(config.get('bin', 'end_row_binning_2'))
+#
+# # print(self.default_dir, self.binning, self.start_column, self.end_column, self.start_row, self.end_row)
+#
+# else:
+# '''
+# 1、如果不存在配置文件,就建立配置文件;
+# 2、并且手动创建配置变量
+# '''
+# config = configparser.ConfigParser()
+#
+# # config.add_section('effective_window')
+# # startRow = 339
+# # endRow = 639
+# # startColumn = 285
+# # endColumn = 1649
+#
+#
+# config.add_section('bin')
+# config.set('bin', 'binning', '1')
+#
+# config.set('bin', 'start_column_binning_1', '12')
+# config.set('bin', 'end_column_binning_1', '1376')
+# config.set('bin', 'start_row_binning_1', '1')
+# config.set('bin', 'end_row_binning_1', '301')
+#
+# config.set('bin', 'start_column_binning_2', '13')
+# config.set('bin', 'end_column_binning_2', '695')
+# config.set('bin', 'start_row_binning_2', '1')
+# config.set('bin', 'end_row_binning_2', '150')
+#
+# config.add_section('image_record_param')
+# config.set('image_record_param', 'image_dir', self.base_dir + '/image')
+# config.set('image_record_param', 'default_image_name', 'testimage')
+# config.set('image_record_param', 'framerate', '20')
+# config.set('image_record_param', 'exposure_time', '500')
+# config.set('image_record_param', 'gain', '0')
+# config.set('image_record_param', 'frame_number', '20')
+#
+# config.add_section('spectral_record_param')
+# config.set('spectral_record_param', 'spectral_dir', self.base_dir + '/spectral')
+# config.set('spectral_record_param', 'default_spectral_name', 'testspectral')
+# # config.set('spectral_record_param', 'start_column_binning_1', '12')
+#
+# with open(self.corning_config_file, mode='w') as f:
+# config.write(f)
+# print('创建配置文件成功!')
+#
+# # 如果没有配置文件,就手动创建配置变量
+# self.image_dir = self.base_dir + '/image'
+# self.create_directory(self.image_dir)
+# self.default_image_name = 'testimage'
+# self.framerate = 20
+# self.exposure_time = 500
+# self.gain = 0
+# self.frame_number = 20
+#
+# self.spectral_dir = self.base_dir + '/spectral'
+# self.create_directory(self.spectral_dir)
+# self.default_spectral_name = 'testspectral'
+#
+# self.binning = int(config.get('bin', 'binning'))
+# self.start_column = int(config.get('bin', 'start_column_binning_1'))
+# self.end_column = int(config.get('bin', 'end_column_binning_1'))
+# self.start_row = int(config.get('bin', 'start_row_binning_1'))
+# self.end_row = int(config.get('bin', 'end_row_binning_1'))
+#
+# # self.start_column = 12
+# # self.end_column = 1376
+# # self.start_row = 1
+# # self.end_row = 300
+#
+# def image_record_param_changed(self, dictionary):
+# '''
+# :param dictionary: {'image_dir':值, 'image_record_param': 值}
+# :return:
+# '''
+# try:
+# # print('接收的参数个数:', len(dictionary.keys()))
+#
+# config = configparser.ConfigParser()
+# config.read(self.corning_config_file)
+#
+# for key in dictionary.keys():
+# if key == 'image_dir':
+# self.image_dir = dictionary[key]
+# config.set('image_record_param', key, dictionary[key])
+# if key == 'default_image_name':
+# self.default_image_name = dictionary[key]
+# config.set('image_record_param', key, dictionary[key])
+# if key == 'framerate':
+# self.framerate = dictionary[key]
+# config.set('image_record_param', key, str(dictionary[key]))
+# if key == 'exposure_time':
+# self.exposure_time = dictionary[key]
+# config.set('image_record_param', key, str(dictionary[key]))
+# if key == 'gain':
+# self.gain = dictionary[key]
+# config.set('image_record_param', key, str(dictionary[key]))
+# if key == 'frame_number':
+# self.frame_number = dictionary[key]
+# config.set('image_record_param', key, str(dictionary[key]))
+# except:
+# traceback.print_exc()
+#
+# with open(self.corning_config_file, 'w') as f:
+# config.write(f)
+#
+# def spectral_record_param_changed(self, dictionary):
+# '''
+# :param dictionary: {'image_dir':值, 'image_record_param': 值}
+# :return:
+# '''
+# print(len(dictionary.keys()))
+#
+# config = configparser.ConfigParser()
+# config.read(self.corning_config_file)
+#
+# try:
+# for key in dictionary.keys():
+# if key == 'spectral_dir':
+# self.spectral_dir = dictionary[key]
+# config.set('spectral_record_param', key, dictionary[key])
+# if key == 'default_spectral_name':
+# self.default_spectral_name = dictionary[key]
+# config.set('spectral_record_param', key, dictionary[key])
+# except:
+# traceback.print_exc()
+#
+# with open(self.corning_config_file, 'w') as f:
+# config.write(f)
+
+
+class ConfigFile(QObject, DirManager):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ image_signal = pyqtSignal(dict)
+ spectral_signal = pyqtSignal(dict)
+
+ def __init__(self):
+ '''
+ 配置文件读取和写入类,采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取并保存在此类中,
+ '''
+ super(ConfigFile, self).__init__()
+
+ self.corning_config_file = self.log_dir + '//corning_config.ini'
+
+ self.read_config_file()
+
+ self.image_signal.connect(self.image_record_param_changed)
+ self.spectral_signal.connect(self.spectral_record_param_changed)
+
+ # 读取配置文件,如果没有就创建
+ def read_config_file(self):
+ if os.path.exists(self.corning_config_file):
+ '''
+ 如果存在配置文件,就从配置文件中读取软件配置信息
+ '''
+ print('配置文件存在!')
+
+ config = configparser.ConfigParser()
+ config.read(self.corning_config_file)
+
+ # self.image_dir = config.get('image_record_param', 'image_dir')
+ # self.create_directory(self.image_dir)
+ # self.default_image_name = config.get('image_record_param', 'default_image_name')
+ # self.framerate = int(config.get('image_record_param', 'framerate'))
+ # self.exposure_time = int(float(config.get('image_record_param', 'exposure_time')))
+ # self.gain = int(float(config.get('image_record_param', 'gain')))
+ # self.frame_number = int(config.get('image_record_param', 'frame_number'))
+ # self.arcus_speed = int(config.get('image_record_param', 'arcus_speed'))
+ #
+ # self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
+ # self.create_directory(self.spectral_dir)
+ # self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
+ # self.spectral_number = int(config.get('spectral_record_param', 'spectral_number'))
+ # self.framenumber_average = int(config.get('spectral_record_param', 'framenumber_average'))
+ # self.exposure_time_spectral = int(config.get('spectral_record_param', 'exposure_time_spectral'))
+ #
+ # self.binning = int(config.get('bin', 'binning'))
+ # if self.binning == 1:
+ # self.start_column = int(config.get('bin', 'start_column_binning_1'))
+ # self.end_column = int(config.get('bin', 'end_column_binning_1'))
+ # self.start_row = int(config.get('bin', 'start_row_binning_1'))
+ # self.end_row = int(config.get('bin', 'end_row_binning_1'))
+ # elif self.binning == 2:
+ # self.start_column = int(config.get('bin', 'start_column_binning_2'))
+ # self.end_column = int(config.get('bin', 'end_column_binning_2'))
+ # self.start_row = int(config.get('bin', 'start_row_binning_2'))
+ # self.end_row = int(config.get('bin', 'end_row_binning_2'))
+ #
+ # # print(self.default_dir, self.binning, self.start_column, self.end_column, self.start_row, self.end_row)
+ else:
+ '''
+ 1、如果不存在配置文件,就建立配置文件;
+ 2、并且手动创建配置变量
+ '''
+ config = configparser.ConfigParser()
+
+
+
+ config.add_section('bin')
+ config.set('bin', 'binning', '1')
+
+ # # Serial number = 008
+ # config.set('bin', 'start_column_binning_1', '12')
+ # config.set('bin', 'end_column_binning_1', '1376')
+ # config.set('bin', 'start_row_binning_1', '2')
+ # config.set('bin', 'end_row_binning_1', '302')
+ #
+ # config.set('bin', 'start_column_binning_2', '13')
+ # config.set('bin', 'end_column_binning_2', '695')
+ # config.set('bin', 'start_row_binning_2', '0')
+ # config.set('bin', 'end_row_binning_2', '150')
+
+ # # Serial number = 0073
+ # config.set('bin', 'start_column_binning_1', '12')
+ # config.set('bin', 'end_column_binning_1', '1376')
+ # config.set('bin', 'start_row_binning_1', '1')
+ # config.set('bin', 'end_row_binning_1', '301')
+ #
+ # config.set('bin', 'start_column_binning_2', '13')
+ # config.set('bin', 'end_column_binning_2', '695')
+ # config.set('bin', 'start_row_binning_2', '0')
+ # config.set('bin', 'end_row_binning_2', '150')
+
+ # # Serial number = 0095
+ # config.set('bin', 'start_column_binning_1', '12')
+ # config.set('bin', 'end_column_binning_1', '1376')
+ # config.set('bin', 'start_row_binning_1', '1')
+ # config.set('bin', 'end_row_binning_1', '301')
+ #
+ # config.set('bin', 'start_column_binning_2', '13')
+ # config.set('bin', 'end_column_binning_2', '695')
+ # config.set('bin', 'start_row_binning_2', '0')
+ # config.set('bin', 'end_row_binning_2', '150')
+
+ # Serial number = 0031
+ config.set('bin', 'start_column_binning_1', '12')
+ config.set('bin', 'end_column_binning_1', '1376')
+ config.set('bin', 'start_row_binning_1', '1')
+ config.set('bin', 'end_row_binning_1', '301')
+
+ config.set('bin', 'start_column_binning_2', '13')
+ config.set('bin', 'end_column_binning_2', '695')
+ config.set('bin', 'start_row_binning_2', '1')
+ config.set('bin', 'end_row_binning_2', '151')
+
+ # # Serial number = 0099
+ # config.set('bin', 'start_column_binning_1', '12')
+ # config.set('bin', 'end_column_binning_1', '1376')
+ # config.set('bin', 'start_row_binning_1', '1')
+ # config.set('bin', 'end_row_binning_1', '301')
+ #
+ # config.set('bin', 'start_column_binning_2', '13')
+ # config.set('bin', 'end_column_binning_2', '695')
+ # config.set('bin', 'start_row_binning_2', '1')
+ # config.set('bin', 'end_row_binning_2', '151')
+
+
+
+ config.add_section('effective_window')
+ config.set('effective_window', 'width_binning_1', '1392')
+ config.set('effective_window', 'offsetX_binning_1', '272')
+ config.set('effective_window', 'height_binning_1', '302')
+ config.set('effective_window', 'offsetY_binning_1', '364')
+
+ config.set('effective_window', 'width_binning_2', '696')
+ config.set('effective_window', 'offsetX_binning_2', '128')
+ config.set('effective_window', 'height_binning_2', '151')
+ config.set('effective_window', 'offsetY_binning_2', '182')
+
+ config.add_section('calibration_file')
+ config.set('calibration_file', 'cal_file_name_image_bining_1', 'lens_bin1_gain_SN0073')
+ config.set('calibration_file', 'cal_file_name_image_bining_2', 'lens_bin2_gain_SN0073')
+
+ config.set('calibration_file', 'cal_file_it_image_bining_1', '6969')
+ config.set('calibration_file', 'cal_file_it_image_bining_2', '1628')
+
+ config.set('calibration_file', 'cal_file_name_spectral_bining_1', 'optical_fiber_bin1_gain_SN0073')
+ config.set('calibration_file', 'cal_file_it_spectrl_bining_1', '42300')
+
+
+
+
+ config.add_section('wavelength_file_name')
+ config.set('wavelength_file_name', 'file_name', 'wavelength0073.txt')
+
+
+
+
+
+ config.add_section('image_record_param')
+ config.set('image_record_param', 'image_dir', self.base_dir + '/image')
+ config.set('image_record_param', 'default_image_name', 'testimage')
+ config.set('image_record_param', 'framerate', '20')
+ config.set('image_record_param', 'exposure_time', '500')
+ config.set('image_record_param', 'gain', '0')
+ config.set('image_record_param', 'frame_number', '20')
+ config.set('image_record_param', 'arcus_speed', '1000')
+
+ config.add_section('spectral_record_param')
+ config.set('spectral_record_param', 'spectral_dir', self.base_dir + '/spectral')
+ config.set('spectral_record_param', 'default_spectral_name', 'testspectral')
+ config.set('spectral_record_param', 'spectral_number', '10')
+ config.set('spectral_record_param', 'framenumber_average', '10')
+ config.set('spectral_record_param', 'exposure_time_spectral', '1000')
+ # config.set('spectral_record_param', 'start_column_binning_1', '12')
+
+ with open(self.corning_config_file, mode='w') as f:
+ config.write(f)# 如果没有配置文件,就手动创建配置变量
+ print('创建配置文件成功!')
+
+
+
+ # 读取配置文件中的参数
+ self.binning = int(config.get('bin', 'binning'))
+ print('读取配置文件中参数:', self.binning)
+
+ if self.binning == 1:
+ self.effective_window_width = int(config.get('effective_window', 'width_binning_1'))
+ self.effective_window_offsetx = int(config.get('effective_window', 'offsetx_binning_1'))
+ self.effective_window_height = int(config.get('effective_window', 'height_binning_1'))
+ self.effective_window_offsety = int(config.get('effective_window', 'offsety_binning_1'))
+
+ self.start_column = int(config.get('bin', 'start_column_binning_1'))
+ self.end_column = int(config.get('bin', 'end_column_binning_1'))
+ self.start_row = int(config.get('bin', 'start_row_binning_1'))
+ self.end_row = int(config.get('bin', 'end_row_binning_1'))
+
+ self.calibration_file_name_image=config.get('calibration_file', 'cal_file_name_image_bining_1')
+ self.calibration_file_it_image = int(config.get('calibration_file', 'cal_file_it_image_bining_1'))
+ self.calibration_file_name_spectral = config.get('calibration_file', 'cal_file_name_spectral_bining_1')
+ self.calibration_file_it_spectral = int(config.get('calibration_file', 'cal_file_it_spectrl_bining_1'))
+ elif self.binning == 2:
+ self.effective_window_width = int(config.get('effective_window', 'width_binning_2'))
+ self.effective_window_offsetx = int(config.get('effective_window', 'offsetx_binning_2'))
+ self.effective_window_height = int(config.get('effective_window', 'height_binning_2'))
+ self.effective_window_offsety = int(config.get('effective_window', 'offsety_binning_2'))
+
+ self.start_column = int(config.get('bin', 'start_column_binning_2'))
+ self.end_column = int(config.get('bin', 'end_column_binning_2'))
+ self.start_row = int(config.get('bin', 'start_row_binning_2'))
+ self.end_row = int(config.get('bin', 'end_row_binning_2'))
+
+ self.calibration_file_name_image = config.get('calibration_file', 'cal_file_name_image_bining_2')
+ self.calibration_file_it_image = int(config.get('calibration_file', 'cal_file_it_image_bining_2'))
+
+ self.wavelength_file_name = config.get('wavelength_file_name', 'file_name')
+
+ self.image_dir = config.get('image_record_param', 'image_dir')
+ self.create_directory(self.image_dir)
+ self.default_image_name = config.get('image_record_param', 'default_image_name')
+ self.framerate = int(float(config.get('image_record_param', 'framerate')))
+ self.exposure_time = int(float(config.get('image_record_param', 'exposure_time')))
+ self.gain = int(float(config.get('image_record_param', 'gain')))
+ self.frame_number = int(float(config.get('image_record_param', 'frame_number')))
+ self.arcus_speed = int(float(config.get('image_record_param', 'arcus_speed')))
+
+ self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
+ self.create_directory(self.spectral_dir)
+ self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
+ self.spectral_number = int(float(config.get('spectral_record_param', 'spectral_number')))
+ self.framenumber_average = int(float(config.get('spectral_record_param', 'framenumber_average')))
+ self.exposure_time_spectral = int(float(config.get('spectral_record_param', 'exposure_time_spectral')))
+
+ # self.start_column = 12
+ # self.end_column = 1376
+ # self.start_row = 1
+ # self.end_row = 300
+
+ def image_record_param_changed(self, dictionary):
+ '''
+ :param dictionary: {'image_dir':值, 'image_record_param': 值}
+ :return:
+ '''
+ try:
+ # print('接收的参数个数:', len(dictionary.keys()))
+
+ config = configparser.ConfigParser()
+ config.read(self.corning_config_file)
+
+ for key in dictionary.keys():
+ # self.key = dictionary[key]
+ # config.set('image_record_param', key, dictionary[key])
+
+ if key == 'image_dir':
+ self.image_dir = dictionary[key]
+ config.set('image_record_param', key, dictionary[key])
+ if key == 'default_image_name':
+ self.default_image_name = dictionary[key]
+ config.set('image_record_param', key, dictionary[key])
+ if key == 'framerate':
+ self.framerate = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'exposure_time':
+ self.exposure_time = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'gain':
+ self.gain = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'frame_number':
+ self.frame_number = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'arcus_speed':
+ self.arcus_speed = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ except:
+ traceback.print_exc()
+
+ with open(self.corning_config_file, 'w') as f:
+ config.write(f)
+
+ def spectral_record_param_changed(self, dictionary):
+ '''
+ :param dictionary: {'image_dir':值, 'image_record_param': 值}
+ :return:
+ '''
+ print(len(dictionary.keys()))
+
+ config = configparser.ConfigParser()
+ config.read(self.corning_config_file)
+
+ try:
+ for key in dictionary.keys():
+ if key == 'spectral_dir':
+ self.spectral_dir = dictionary[key]
+ config.set('spectral_record_param', key, dictionary[key])
+ if key == 'default_spectral_name':
+ self.default_spectral_name = dictionary[key]
+ config.set('spectral_record_param', key, dictionary[key])
+ if key == 'spectral_number':
+ self.spectral_number = dictionary[key]
+ config.set('spectral_record_param', key, str(dictionary[key]))
+ if key == 'framenumber_average':
+ self.framenumber_average = dictionary[key]
+ config.set('spectral_record_param', key, str(dictionary[key]))
+ if key == 'exposure_time_spectral':
+ self.exposure_time_spectral = dictionary[key]
+ config.set('spectral_record_param', key, str(dictionary[key]))
+ except:
+ traceback.print_exc()
+
+ with open(self.corning_config_file, 'w') as f:
+ config.write(f)
+
+
+if __name__ == '__main__':
+ x = ConfigFile()
diff --git a/library/dir_manager.py b/library/dir_manager.py
new file mode 100644
index 0000000..84e3a3d
--- /dev/null
+++ b/library/dir_manager.py
@@ -0,0 +1,29 @@
+import os
+from library.functions import get_path
+
+
+class DirManager():
+ def __init__(self):
+ self.base_dir = get_path()
+ self.log_dir = self.base_dir + '//log'
+
+ self.create_directory(self.log_dir)
+ print(self.log_dir)
+
+
+ # 查看是否存在保存光谱和影像文件的目录,如果没有就创建
+ def create_directory(self, directory):
+ '''
+ :param directory: 需要创建的文件夹绝对路径,不能将参数directory省略而在此函数内部使用self.log_dir,
+ 因为本类的继承类也需要使用此函数
+ :return:
+ '''
+ if not os.path.exists(directory):
+ print('创建文件夹:', directory)
+ os.makedirs(directory)
+ # else:
+ # print('文件夹存在:%s' % self.log_dir)
+
+
+if __name__ == '__main__':
+ x = DirManager()
diff --git a/library/functions.py b/library/functions.py
new file mode 100644
index 0000000..29e73d6
--- /dev/null
+++ b/library/functions.py
@@ -0,0 +1,144 @@
+# -*- coding:utf-8 -*-
+
+'''
+本模块是各种工具函数
+'''
+
+import sys, os
+import numpy as np
+
+def get_path():
+ '''
+ 本函数说明:https://pythonhosted.org/PyInstaller/runtime-information.html#using-sys-executable-and-sys-argv-0
+ :return: 返回运行程序的绝对路径
+ '''
+ frozen = 'not'
+ if getattr(sys, 'frozen', False):
+ # we are running in a bundle
+ bundle_dir = sys._MEIPASS
+
+ # print('we are running in a bundle(pyinstaller打包程序)!')
+ else:
+ # we are running in a normal Python environment
+ # bundle_dir = os.path.dirname(os.path.abspath(__file__)) # 此行代码返回的是本文件的路径,而不是本文件所导入的文件的路径
+ bundle_dir = os.getcwd()
+ # print('we are running in a normal Python environment(非pyinstaller打包程序)!')
+
+ return bundle_dir
+
+
+def get_resource_path(relative_path):
+ '''
+ 本函数说明:https://www.zacoding.com/en/post/python-selenium-to-exe/
+ :param relative_path:
+ :return:
+ '''
+ try:
+ base_path = sys._MEIPASS
+ except Exception:
+ base_path = os.getcwd()
+ return os.path.join(base_path, relative_path)
+
+
+def percentile_stretching(img, lowPercentile=0, highPercentile=100, minout=0, maxout=255):
+ '''
+ 本程序用于拉伸影像
+ :param img:
+ :param lowPercentile:
+ :param highPercentile:
+ :param minout:
+ :param maxout:
+ :return:
+ '''
+ if len(img.shape) == 2:
+ low = np.percentile(img, lowPercentile)
+ up = np.percentile(img, highPercentile)
+
+ img_new = ((img - low) / (up - low)) * (maxout - minout) + minout
+ img_new[img_new < minout] = minout
+ img_new[img_new > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+ else: # 对于彩色照片,需要先单独对每个波段拉伸
+ img_new = np.empty(img.shape)
+ for i in range(img.shape[2]):
+ low = np.percentile(img[:, :, i], lowPercentile)
+ up = np.percentile(img[:, :, i], highPercentile)
+
+ img_new[:, :, i] = minout + ((img[:, :, i] - low) / (up - low)) * (maxout - minout)
+ img_new[:, :, i][img_new[:, :, i] < minout] = minout
+ img_new[:, :, i][img_new[:, :, i] > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+
+
+def return_file_path(out, filepath, filename, model='image'):
+ '''
+ 本程序功能:在filepath中寻找所有包含filename所有文件(filename1、filename2),然后返回一个filename3
+ :param out: 永远传入一个空list:[];用于存储所有递归调用
+ :param filepath:
+ :param filename:
+ :param model: 有两个模式:image 和 spectral
+ :return:
+ '''
+
+ # 出现此处代码的原因是:当次函数定义执行后,函数定义就包含了out参数的引用,
+ # 而out参数是可变参数,每一次调用次函数都会改变out的值,所有不能保证每次调用此函数时out==[]。
+ # 当第二次调用此方程时
+ # if out != []:
+ # if filename not in os.path.splitext(out[-1]):
+ # out = []
+
+ if model == 'image':
+ files = os.listdir(filepath)
+ for s in files:
+ abspath = os.path.join(filepath, s)
+ if os.path.isfile(abspath):
+ tmp = os.path.splitext(os.path.split(abspath)[1])[0]
+ if tmp not in out: # 防止重复记录
+ if filename in tmp:
+ out.append(tmp)
+ else:
+ pass
+ # print('没有进来')
+ elif os.path.isdir(abspath):
+ return_file_path(out, abspath, filename)
+ out.sort(key=lambda x: int(x.replace(filename, '')))
+
+ if out == []:
+ x = filename + str(0)
+ return os.path.join(filepath, x), 0
+ if out != []:
+ number = int(out[-1].replace(filename, '')) + 1
+ x = filename + str(number)
+ return os.path.join(filepath, x), number
+ elif model == 'spectral':
+ files = os.listdir(filepath)
+ for s in files:
+ abspath = os.path.join(filepath, s)
+ if os.path.isfile(abspath) and os.path.splitext(s)[1] == '.txt':
+ tmp = os.path.splitext(os.path.split(abspath)[1])[0]
+ if tmp not in out: # 防止重复记录
+ if filename in tmp:
+ out.append(tmp)
+ elif os.path.isdir(abspath):
+ return_file_path(out, abspath, filename)
+ out.sort(key=lambda x: int(x.replace(filename, '')))
+
+ if out == []:
+ x = filename + str(0) + '.txt'
+ return os.path.join(filepath, x), 0
+ if out != []:
+ number = int(out[-1].replace(filename, '')) + 1 # 现存最大文件号 + 1
+ x = filename + str(number) + '.txt'
+ return os.path.join(filepath, x), number
+
+
+if __name__ == '__main__':
+ # print(get_path())
+
+ x = return_file_path([], r'D:\delete', 'sss', model='spectral')
+ print(x)
+
+ # y = return_file_path([], r'D:\delete', 'rr')
+ # print(y)
diff --git a/library/image_reader_writer.py b/library/image_reader_writer.py
new file mode 100644
index 0000000..e2719f5
--- /dev/null
+++ b/library/image_reader_writer.py
@@ -0,0 +1,40 @@
+import sys, traceback
+from osgeo import gdal
+
+# 读写影像类
+class ImageReaderWriter(object):
+
+ #读图像文件
+ @classmethod
+ def read_img(cls, filename, xoff=0, yoff=0, im_width=None, im_height=None):
+ try:
+ dataset = gdal.Open(filename) # 打开文件
+ if im_width == None:
+ im_width = dataset.RasterXSize # 栅格矩阵的列数
+ if im_height == None:
+ im_height = dataset.RasterYSize # 栅格矩阵的行数
+ num_bands = dataset.RasterCount # 栅格矩阵的波段数
+ im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
+ im_proj = dataset.GetProjection() # 地图投影信息
+ im_data = dataset.ReadAsArray(xoff, yoff, im_width, im_height) # 将数据写成数组,对应栅格矩阵
+ del dataset
+ return im_proj, im_geotrans, im_data
+ except AttributeError:
+ print('gdal打开影像:没有文件!')
+ except Exception:
+ traceback.print_exc()
+ pass
+
+ #写文件,以写成tif为例
+ @classmethod
+ def write_img(cls, dst_filename, data):
+ format = "ENVI"
+ driver = gdal.GetDriverByName(format)
+ RasterXSize = data.shape[2] # 遥感影像的sample(列数)
+ RasterYSize = data.shape[1] # 遥感影像的line(行数)
+ band = data.shape[0]
+ # driver.Create()函数中RasterXSize代表影像的sample(列数),RasterYSize代表影像的line(行数)
+ dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize, band, gdal.GDT_Float32)
+ for i in range(band):
+ dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始,所以dst_ds.GetRasterBand(i+1)
+ dst_ds = None
\ No newline at end of file
diff --git a/library/log.py b/library/log.py
new file mode 100644
index 0000000..8198e57
--- /dev/null
+++ b/library/log.py
@@ -0,0 +1,50 @@
+# 标准库
+import traceback, os, logging
+
+# 三方库
+import configparser
+
+# 自己写的库
+from library.dir_manager import DirManager
+
+
+class Log(DirManager):
+ def __init__(self):
+ super(Log, self).__init__()
+
+ self.log()
+
+ def log(self):
+ # 判断是否存在log文件,如果不存在就创建
+ if not os.path.exists(self.log_dir + '//all_operate.log'):
+ with open(self.log_dir + '//all_operate.log', 'w') as f:
+ pass
+ if not os.path.exists(self.log_dir + '//error.log'):
+ with open(self.log_dir + '//error.log', 'w') as f:
+ pass
+
+ # 初始化log
+ root_logger = logging.getLogger('root')
+ root_logger.setLevel(level=logging.DEBUG) # logger级别设置为低级别,代表这个logger可以处理很多级别的日志,更灵活的处理放在logger中的各种handler中
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+
+ all_operate_file_handler = logging.FileHandler(self.log_dir + '//all_operate.log') # 输出到文件
+ all_operate_file_handler.setLevel(logging.INFO)
+ all_operate_file_handler.setFormatter(formatter)
+
+ error_file_handler = logging.FileHandler(self.log_dir + '//error.log') # 输出到文件
+ error_file_handler.setLevel(logging.ERROR)
+ error_file_handler.setFormatter(formatter)
+
+ stream_handler = logging.StreamHandler() # 输出到控制台
+ stream_handler.setLevel(logging.INFO)
+ stream_handler.setFormatter(formatter)
+
+ root_logger.addHandler(all_operate_file_handler)
+ root_logger.addHandler(error_file_handler)
+ root_logger.addHandler(stream_handler)
+
+
+if __name__ == '__main__':
+ x = Log()
diff --git a/library/log/corning_config.ini b/library/log/corning_config.ini
new file mode 100644
index 0000000..5951427
--- /dev/null
+++ b/library/log/corning_config.ini
@@ -0,0 +1,25 @@
+[bin]
+binning = 1
+start_column_binning_1 = 12
+end_column_binning_1 = 1376
+start_row_binning_1 = 1
+end_row_binning_1 = 301
+start_column_binning_2 = 13
+end_column_binning_2 = 695
+start_row_binning_2 = 1
+end_row_binning_2 = 150
+
+[image_record_param]
+image_dir = D:\py_program\corning410\library/image
+default_image_name = test_image
+framerate = 20
+exposure_time = 500
+gain = 0
+frame_number = 20
+
+[spectral_record_param]
+spectral_dir = D:\py_program\corning410\library/spectral
+default_spectral_name = test_spectral
+spectral_number = 10
+framenumber_average = 10
+
diff --git a/library/matplotlib_display_image_spectral.py b/library/matplotlib_display_image_spectral.py
new file mode 100644
index 0000000..81a925f
--- /dev/null
+++ b/library/matplotlib_display_image_spectral.py
@@ -0,0 +1,161 @@
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.figure import Figure
+import traceback
+import time, sys
+from functions import percentile_stretching
+
+from PyQt5 import QtWidgets, QtCore, uic
+import pyqtgraph as pg
+from random import randint
+
+
+class ArgsError(Exception):
+ pass
+
+# 画图类,用于:画出采集到的光谱;调焦(影响模式调焦)
+class MatplotlibSpectralViewer(FigureCanvas):
+ def __init__(self, xlabel=None, ylabel=None, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MatplotlibSpectralViewer, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ self.axes.set_ylabel('reflectance')
+
+ self.xlabel = xlabel
+ self.ylabel = ylabel
+
+ self._plotref = None # 这里代表曲线
+
+ self.axes.set_ylim(0, 1.2)
+
+ # 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot_wrap(self, *args):
+ if self.xlabel is not None:
+ self.axes.set_xlabel(self.xlabel)
+ if self.ylabel is not None:
+ self.axes.set_ylabel(self.ylabel)
+
+ try:
+ if self._plotref == None:
+ if len(args) == 0:
+ raise ArgsError('传入了0个参数,本函数只能传入1/2个参数!')
+ elif len(args) == 1:
+ self.axes.cla()
+
+ # self.axes.set_ylim(0, 1.2)
+
+ self._plotref = self.axes.plot(list(range(len(args[0]))), args[0])[0]
+ self.draw()
+ elif len(args) == 2:
+ self.axes.cla()
+
+ # self.axes.set_ylim(0, 1.2)
+
+ self._plotref = self.axes.plot(args[0], args[1])[0]
+ self.draw()
+ elif len(args) > 2:
+ raise ArgsError('传入了大于2个参数,本函数只能传入1/2个参数!')
+ elif self._plotref is not None:
+ if len(args) == 0:
+ raise ArgsError('传入了0个参数,本函数只能传入1/2个参数!')
+ elif len(args) == 1:
+ self._plotref.set_data(list(range(len(args[0]))), args[0])
+
+ # 更新显示区域
+ self.axes.set_xlim(min(list(range(len(args[0])))), max(list(range(len(args[0])))))
+ self.axes.set_ylim(min(args[0]), max(args[0]))
+
+ # self.axes.set_ylim(0, 1.2)
+
+ # 绘制图像
+ self.draw()
+ elif len(args) == 2:
+ self._plotref.set_data(args[0], args[1])
+
+ # 更新显示区域
+ self.axes.set_xlim(min(args[0]), max(args[0]))
+ self.axes.set_ylim(min(args[1]), max(args[1]))
+
+ # self.axes.set_ylim(0, 1.2)
+
+ # 绘制图像
+ self.draw()
+ elif len(args) > 2:
+ raise ArgsError('传入了大于2个参数,本函数只能传入1/2个参数!')
+ except Exception:
+ traceback.print_exc()
+
+
+# 画图类,用于:画出采集到的图像;显示帧流(光谱模式对准光纤)
+class MatplotlibImageViewer(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MatplotlibImageViewer, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+
+ self._plotref = None # 这里代表图像
+
+ # 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def setImage(self, image, lowPercentile=0, highPercentile=100):
+ self.axes.set_xticks([])
+ self.axes.set_yticks([])
+
+ if self._plotref == None:
+ self._plotref = self.axes.imshow(image)
+ self.draw()
+ elif self._plotref is not None:
+ self._plotref.set_data(percentile_stretching(image, lowPercentile, highPercentile))
+ self.draw()
+
+
+class MainWindow(QtWidgets.QMainWindow):
+ def __init__(self, *args, **kwargs):
+ super(MainWindow, self).__init__(*args, **kwargs)
+
+ # self.graphWidget = QtSpectralViewer()
+ self.graphWidget = MatplotlibSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
+ self.setCentralWidget(self.graphWidget)
+
+ self.x = list(range(100)) # 100 time points
+ self.y = [randint(0, 100) for _ in range(100)] # 100 data points
+
+ # self.graphWidget.setBackground('w')
+
+ pen = pg.mkPen(color=(255, 0, 0))
+ self.graphWidget.plot_wrap(self.x, self.y)
+
+ self.timer = QtCore.QTimer()
+ self.timer.timeout.connect(self.update_plot_data)
+ self.timer.start(10)
+
+ def update_plot_data(self):
+ self.x = self.x[1:] # Remove the first y element.
+ self.x.append(self.x[-1] + 1) # Add a new value 1 higher than the last.
+
+ self.y = self.y[1:] # Remove the first
+ self.y.append(randint(0, 100)) # Add a new random value.
+
+ # self.data_line.setData(self.x, self.y) # Update the data.
+
+ self.graphWidget.plot_wrap(self.x, self.y)
+
+
+if __name__ == '__main__':
+ app = QtWidgets.QApplication(sys.argv)
+ w = MainWindow()
+ w.show()
+ sys.exit(app.exec_())
diff --git a/library/message_box.py b/library/message_box.py
new file mode 100644
index 0000000..035cbb0
--- /dev/null
+++ b/library/message_box.py
@@ -0,0 +1,53 @@
+from PyQt5.QtWidgets import QApplication, QDialog
+from PyQt5.QtCore import Qt
+
+import sys
+
+from library.message_box_ui import *
+
+
+class MessageBox(QDialog, Ui_message_box_ui):
+ def __init__(self, txt, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(MessageBox, self).__init__(parent)
+ self.setupUi(self)
+
+ # self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:只能在关闭此窗口之后才能操作后面的窗口,但是不会阻塞调用此窗口的进程的代码;此行代码必须放在show()函数之前
+ # self.setWindowModality(Qt.WindowModal)
+
+ # 无边框
+ # self.setWindowFlags(Qt.FramelessWindowHint)
+
+ self.txt = txt
+
+ self.info()
+
+ self.confirm_bt.clicked.connect(self.shutdown)
+
+ # 禁止调整大小
+ # self.setFixedSize(self.width(), self.height())
+
+ def info(self):
+ self.info_label.setText(self.txt)
+
+ # self.exec() # 阻塞调用此窗口后的进程的代码,只有此窗口返回后才能执行此窗口外的代码
+
+ # self.show() # 只是显示,不会阻塞任何代码
+
+ def shutdown(self):
+ self.close()
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ x = MessageBox('请先曝光和采集暗电流!')
+
+ # x.show()
+
+ sys.exit(app.exec_())
diff --git a/library/message_box_ui.py b/library/message_box_ui.py
new file mode 100644
index 0000000..833cb29
--- /dev/null
+++ b/library/message_box_ui.py
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'message_box_ui.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_message_box_ui(object):
+ def setupUi(self, message_box_ui):
+ message_box_ui.setObjectName("message_box_ui")
+ message_box_ui.resize(487, 385)
+ self.gridLayout = QtWidgets.QGridLayout(message_box_ui)
+ self.gridLayout.setObjectName("gridLayout")
+ self.info_label = QtWidgets.QLabel(message_box_ui)
+ self.info_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/\n"
+" /*color:white;*/\n"
+" /*背景颜色*/\n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.info_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.info_label.setObjectName("info_label")
+ self.gridLayout.addWidget(self.info_label, 0, 0, 1, 1)
+ self.confirm_bt = QtWidgets.QPushButton(message_box_ui)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.confirm_bt.sizePolicy().hasHeightForWidth())
+ self.confirm_bt.setSizePolicy(sizePolicy)
+ self.confirm_bt.setMinimumSize(QtCore.QSize(0, 130))
+ self.confirm_bt.setAcceptDrops(False)
+ self.confirm_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.confirm_bt.setObjectName("confirm_bt")
+ self.gridLayout.addWidget(self.confirm_bt, 1, 0, 1, 1)
+
+ self.retranslateUi(message_box_ui)
+ QtCore.QMetaObject.connectSlotsByName(message_box_ui)
+
+ def retranslateUi(self, message_box_ui):
+ _translate = QtCore.QCoreApplication.translate
+ message_box_ui.setWindowTitle(_translate("message_box_ui", "提示"))
+ self.info_label.setText(_translate("message_box_ui", "提示信息"))
+ self.confirm_bt.setText(_translate("message_box_ui", "确定"))
diff --git a/library/message_box_ui.ui b/library/message_box_ui.ui
new file mode 100644
index 0000000..97fa41d
--- /dev/null
+++ b/library/message_box_ui.ui
@@ -0,0 +1,106 @@
+
+
+ message_box_ui
+
+
+
+ 0
+ 0
+ 487
+ 385
+
+
+
+ 提示
+
+
+ -
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 提示信息
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 130
+
+
+
+ false
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 确定
+
+
+
+
+
+
+
+
diff --git a/library/multithread.py b/library/multithread.py
new file mode 100644
index 0000000..769188c
--- /dev/null
+++ b/library/multithread.py
@@ -0,0 +1,81 @@
+import sys, traceback
+from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, pyqtSlot
+
+class WorkerSignals(QObject):
+ '''
+ Defines the signals available from a running worker thread.
+
+ Supported signals are:
+
+ finished
+ No data
+
+ error
+ `tuple` (exctype, value, traceback.format_exc() )
+
+ result
+ `object` data returned from processing, anything
+
+ progress
+ `int` indicating % progress
+
+ # 信号必须定义为类属性,不能放在__init__方法里
+ '''
+ finished = pyqtSignal()
+ error = pyqtSignal(tuple)
+ result = pyqtSignal(object)
+ progress = pyqtSignal(int) # 可以用作进度条
+
+ serial = pyqtSignal(object) # 2record_system_v26的此信号移动到类SerialPort中了
+
+ image_signal = pyqtSignal(dict) # 只用在2record_system_v25中
+ spectral_signal = pyqtSignal(dict) # 只用在2record_system_v25中
+
+ openinfo = pyqtSignal(int) # 只用在2record_system_v25中
+ plotsignal = pyqtSignal() # 2record_system_v26的此信号移动到类ImageWindowPhone中了
+
+# https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+# 用于qt多线程:运行long-time task
+class Worker(QRunnable):
+ '''
+ Worker thread
+
+ Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
+
+ :param callback: The function callback to run on this worker thread. Supplied args and
+ kwargs will be passed through to the runner.
+ :type callback: function
+ :param args: Arguments to pass to the callback function
+ :param kwargs: Keywords to pass to the callback function
+
+ '''
+
+ def __init__(self, fn, *args, **kwargs):
+ super(Worker, self).__init__()
+
+ # Store constructor arguments (re-used for processing)
+ self.fn = fn
+ self.args = args
+ self.kwargs = kwargs
+ self.signals = WorkerSignals()
+
+ # Add the callback to our kwargs
+ # self.kwargs['progress_callback'] = self.signals.progress
+
+ @pyqtSlot()
+ def run(self):
+ '''
+ Initialise the runner function with passed args, kwargs.
+ '''
+ try: # 如果有错,就捕捉错误
+ result = self.fn(*self.args, **self.kwargs)
+ except Exception: # 根据错误进行处理
+ traceback.print_exc()
+ exctype, value = sys.exc_info()[:2]
+
+ self.signals.error.emit((exctype, value, traceback.format_exc()))
+ else: # 如果没有错误执行下面代码
+ self.signals.finished.emit() # Done
+ self.signals.result.emit(result) # Return the result of the processing
+ finally: # 不管有错无错,都要执行下面代码
+ pass
\ No newline at end of file
diff --git a/pyqt_multithread.py b/pyqt_multithread.py
new file mode 100644
index 0000000..a16ae77
--- /dev/null
+++ b/pyqt_multithread.py
@@ -0,0 +1,143 @@
+from PyQt5.QtGui import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtCore import *
+
+import time
+import traceback, sys
+
+
+class WorkerSignals(QObject):
+ '''
+ Defines the signals available from a running worker thread.
+
+ Supported signals are:
+
+ finished
+ No data
+
+ error
+ `tuple` (exctype, value, traceback.format_exc() )
+
+ result
+ `object` data returned from processing, anything
+
+ progress
+ `int` indicating % progress
+
+ '''
+ finished = pyqtSignal()
+ error = pyqtSignal(tuple)
+ result = pyqtSignal(object)
+ progress = pyqtSignal(int)
+
+
+class Worker(QRunnable):
+ '''
+ Worker thread
+
+ Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
+
+ :param callback: The function callback to run on this worker thread. Supplied args and
+ kwargs will be passed through to the runner.
+ :type callback: function
+ :param args: Arguments to pass to the callback function
+ :param kwargs: Keywords to pass to the callback function
+
+ '''
+
+ def __init__(self, fn, *args, **kwargs):
+ super(Worker, self).__init__()
+
+ # Store constructor arguments (re-used for processing)
+ self.fn = fn
+ self.args = args
+ self.kwargs = kwargs
+ self.signals = WorkerSignals()
+
+ # Add the callback to our kwargs
+ self.kwargs['progress_callback'] = self.signals.progress
+
+ @pyqtSlot()
+ def run(self):
+ '''
+ Initialise the runner function with passed args, kwargs.
+ '''
+
+ # Retrieve args/kwargs here; and fire processing using them
+ try:
+ result = self.fn(*self.args, **self.kwargs)
+ except:
+ traceback.print_exc()
+ exctype, value = sys.exc_info()[:2]
+ self.signals.error.emit((exctype, value, traceback.format_exc()))
+ else:
+ self.signals.result.emit(result) # Return the result of the processing
+ finally:
+ self.signals.finished.emit() # Done
+
+
+class MainWindow(QMainWindow):
+
+ def __init__(self, *args, **kwargs):
+ super(MainWindow, self).__init__(*args, **kwargs)
+
+ self.counter = 0
+
+ layout = QVBoxLayout()
+
+ self.l = QLabel("Start")
+ b = QPushButton("DANGER!")
+ b.pressed.connect(self.oh_no)
+
+ layout.addWidget(self.l)
+ layout.addWidget(b)
+
+ w = QWidget()
+ w.setLayout(layout)
+
+ self.setCentralWidget(w)
+
+ self.show()
+
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ self.timer = QTimer()
+ self.timer.setInterval(1000)
+ self.timer.timeout.connect(self.recurring_timer)
+ self.timer.start()
+
+ def progress_fn(self, n):
+ print("%d%% done" % n)
+
+ def execute_this_fn(self, progress_callback):
+ for n in range(0, 5):
+ time.sleep(1)
+ progress_callback.emit(n * 100 / 4)
+
+ return "Done."
+
+ def print_output(self, s):
+ print(s)
+
+ def thread_complete(self):
+ print("THREAD COMPLETE!")
+
+ def oh_no(self):
+ # Pass the function to execute
+ worker = Worker(self.execute_this_fn) # Any other args, kwargs are passed to the run function
+ worker.signals.result.connect(self.print_output)
+ worker.signals.finished.connect(self.thread_complete)
+ worker.signals.progress.connect(self.progress_fn)
+
+ # Execute
+ self.threadpool.start(worker)
+
+ def recurring_timer(self):
+ self.counter += 1
+ self.l.setText("Counter: %d" % self.counter)
+
+
+app = QApplication([])
+window = MainWindow()
+app.exec_()
\ No newline at end of file
diff --git a/record_system_v11/1record_system_v1.1.py b/record_system_v11/1record_system_v1.1.py
new file mode 100644
index 0000000..998e772
--- /dev/null
+++ b/record_system_v11/1record_system_v1.1.py
@@ -0,0 +1,230 @@
+from ximea import xiapi
+import cv2
+import numpy as np
+import matplotlib.pyplot as plt
+from osgeo import gdal #读写影像数据
+import os, sys, traceback
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+
+#create instance for first connected camera
+cam = xiapi.Camera()
+
+#start communication to open specific device, use: cam.open_device_by_SN('41305651')
+print('Opening first camera...')
+cam.open_device()
+
+# 打开相机后,显示相机信息
+print('SN: %s'% str(cam.get_device_sn(), encoding = "utf-8"))
+print('Device name: %s'% str(cam.get_device_name(), encoding = "utf-8"))
+print('Device name: %s'% str(cam.get_device_type(), encoding = "utf-8"))
+print('Instance path: %s'% str(cam.get_device_inst_path(), encoding = "utf-8")) # Returns device instance path in operating system.
+print('Location path: %s'% str(cam.get_device_loc_path(), encoding = "utf-8"))
+
+# debug_level、线程数和horizontal flip
+print('Debug level: %s' % cam.get_debug_level())
+print('Default number of threads per image processor: %d' % cam.get_proc_num_threads())
+cam.set_proc_num_threads(8)
+print('Current number of threads per image processor: %d' % cam.get_proc_num_threads())
+print('Is horizontal flip enabled?, %s' % str(cam.is_horizontal_flip()))
+
+
+#采集模式:This mode is supported by selected camera families: CB, MC, MT, MX
+cam.set_acq_timing_mode('XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+mode_used = cam.get_acq_timing_mode()
+if mode_used == 'XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT':
+ print('Mode is XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+else:
+ print('Mode is not XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ sys.exit()
+
+#settings,cam.set_param("exposure",10000)
+exposure = 50
+framerate = 2
+cam.set_exposure(exposure)#曝光时间单位为微秒,1s共有1000000微秒
+cam.set_framerate(framerate)
+print('Exposure was set to %i us' % cam.get_exposure())
+print('Framerate was set to %i FPS' % cam.get_framerate())
+
+# # 设置binning参数
+# # XI_BIN_MODE_SUM(默认): The response from the combined pixels will be added, resulting in increased sensitivity.
+# # XI_BIN_MODE_AVERAGE: The response from the combined pixels will be averaged, resulting in increased signal/noise ratio.
+bin_spec = 2
+bin_spatial = 2
+
+cam.set_binning_selector('XI_BIN_SELECT_HOST_CPU') # 默认为XI_BIN_SELECT_SENSOR(会报错),不可用:XI_BIN_SELECT_DEVICE_FPGA
+cam.set_binning_horizontal_mode('XI_BIN_MODE_SUM')
+cam.set_binning_horizontal(bin_spatial)
+cam.set_binning_vertical_mode('XI_BIN_MODE_SUM')
+cam.set_binning_vertical(bin_spec)
+
+
+# cam.get_width_increment() -->16
+# cam.get_height_increment() -->2
+# cam.get_offsetX_increment() -->16
+# cam.get_offsetY_increment() -->2
+# 设置有效输出窗口
+
+if bin_spatial == 1:
+ cam.set_width(1392)
+ cam.set_offsetX(272)
+
+ cam.set_height(302)
+ cam.set_offsetY(338)
+elif bin_spatial == 2:
+ cam.set_width(696)
+ cam.set_offsetX(128)
+
+ cam.set_height(151)
+ cam.set_offsetY(168)
+
+
+# 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+# 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+# 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype(' dtype('
+
+ arcus_ui
+
+
+
+ 0
+ 0
+ 354
+ 171
+
+
+
+ MainWindow
+
+
+
+
+
+ 100
+ 90
+ 61
+ 21
+
+
+
+ 左
+
+
+
+
+
+ 170
+ 90
+ 61
+ 23
+
+
+
+ 右
+
+
+
+
+
+ 101
+ 10
+ 131
+ 20
+
+
+
+
+
+
+ 100
+ 40
+ 131
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v21/enter_window.py b/record_system_v21/enter_window.py
new file mode 100644
index 0000000..9f5f1cd
--- /dev/null
+++ b/record_system_v21/enter_window.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'enter_window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_enter_Window(object):
+ def setupUi(self, enter_Window):
+ enter_Window.setObjectName("enter_Window")
+ enter_Window.resize(651, 474)
+ self.centralwidget = QtWidgets.QWidget(enter_Window)
+ self.centralwidget.setObjectName("centralwidget")
+ self.image_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.image_mode_bt.setGeometry(QtCore.QRect(200, 180, 111, 51))
+ self.image_mode_bt.setObjectName("image_mode_bt")
+ self.spectral_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.spectral_mode_bt.setGeometry(QtCore.QRect(360, 180, 111, 51))
+ self.spectral_mode_bt.setObjectName("spectral_mode_bt")
+ self.camstatus_tb = QtWidgets.QTextBrowser(self.centralwidget)
+ self.camstatus_tb.setGeometry(QtCore.QRect(200, 240, 271, 81))
+ self.camstatus_tb.setObjectName("camstatus_tb")
+ enter_Window.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(enter_Window)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 651, 26))
+ self.menubar.setObjectName("menubar")
+ enter_Window.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(enter_Window)
+ self.statusbar.setObjectName("statusbar")
+ enter_Window.setStatusBar(self.statusbar)
+ self.actionwew_e = QtWidgets.QAction(enter_Window)
+ self.actionwew_e.setObjectName("actionwew_e")
+
+ self.retranslateUi(enter_Window)
+ QtCore.QMetaObject.connectSlotsByName(enter_Window)
+
+ def retranslateUi(self, enter_Window):
+ _translate = QtCore.QCoreApplication.translate
+ enter_Window.setWindowTitle(_translate("enter_Window", "主窗口"))
+ self.image_mode_bt.setText(_translate("enter_Window", "影像模式"))
+ self.spectral_mode_bt.setText(_translate("enter_Window", "光谱模式"))
+ self.actionwew_e.setText(_translate("enter_Window", "wew e"))
diff --git a/record_system_v21/enter_window.ui b/record_system_v21/enter_window.ui
new file mode 100644
index 0000000..4c39418
--- /dev/null
+++ b/record_system_v21/enter_window.ui
@@ -0,0 +1,73 @@
+
+
+ enter_Window
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+
+
+ 200
+ 180
+ 111
+ 51
+
+
+
+ 影像模式
+
+
+
+
+
+ 360
+ 180
+ 111
+ 51
+
+
+
+ 光谱模式
+
+
+
+
+
+ 200
+ 240
+ 271
+ 81
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v21/image_Window.py b/record_system_v21/image_Window.py
new file mode 100644
index 0000000..53dc349
--- /dev/null
+++ b/record_system_v21/image_Window.py
@@ -0,0 +1,231 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window(object):
+ def setupUi(self, image_Window):
+ image_Window.setObjectName("image_Window")
+ image_Window.setEnabled(True)
+ image_Window.resize(1181, 683)
+ image_Window.setMouseTracking(False)
+ image_Window.setAutoFillBackground(False)
+ image_Window.setSizeGripEnabled(False)
+ image_Window.setModal(False)
+ self.verticalLayout_7 = QtWidgets.QVBoxLayout(image_Window)
+ self.verticalLayout_7.setObjectName("verticalLayout_7")
+ self.groupBox_5 = QtWidgets.QGroupBox(image_Window)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
+ self.groupBox_5.setSizePolicy(sizePolicy)
+ self.groupBox_5.setObjectName("groupBox_5")
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.groupBox_5)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem)
+ self.splitter_3 = QtWidgets.QSplitter(self.groupBox_5)
+ self.splitter_3.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter_3.setObjectName("splitter_3")
+ self.layoutWidget = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(self.layoutWidget)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.label_4 = QtWidgets.QLabel(self.layoutWidget)
+ self.label_4.setObjectName("label_4")
+ self.verticalLayout.addWidget(self.label_4)
+ self.layoutWidget1 = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget1.setObjectName("layoutWidget1")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget1)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.filepath_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filepath_le.setObjectName("filepath_le")
+ self.verticalLayout_2.addWidget(self.filepath_le)
+ self.filename_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filename_le.setObjectName("filename_le")
+ self.verticalLayout_2.addWidget(self.filename_le)
+ self.layoutWidget2 = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget2.setObjectName("layoutWidget2")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.layoutWidget2)
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.filepath_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.verticalLayout_3.addWidget(self.filepath_bt)
+ self.save_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout_3.addWidget(self.save_bt)
+ self.horizontalLayout_4.addWidget(self.splitter_3)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem1)
+ self.verticalLayout_7.addWidget(self.groupBox_5)
+ self.splitter = QtWidgets.QSplitter(image_Window)
+ self.splitter.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter.setObjectName("splitter")
+ self.groupBox_3 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth())
+ self.groupBox_3.setSizePolicy(sizePolicy)
+ self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0))
+ self.groupBox_3.setMaximumSize(QtCore.QSize(2000, 16777215))
+ self.groupBox_3.setObjectName("groupBox_3")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_3)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.groupBox = QtWidgets.QGroupBox(self.groupBox_3)
+ self.groupBox.setObjectName("groupBox")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.horizontalLayout.addLayout(self.image_glo)
+ self.verticalLayout_4.addWidget(self.groupBox)
+ self.statu_tb = QtWidgets.QTextBrowser(self.groupBox_3)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.statu_tb.sizePolicy().hasHeightForWidth())
+ self.statu_tb.setSizePolicy(sizePolicy)
+ self.statu_tb.setMaximumSize(QtCore.QSize(8777215, 100))
+ self.statu_tb.setReadOnly(True)
+ self.statu_tb.setObjectName("statu_tb")
+ self.verticalLayout_4.addWidget(self.statu_tb)
+ self.groupBox_4 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_4.sizePolicy().hasHeightForWidth())
+ self.groupBox_4.setSizePolicy(sizePolicy)
+ self.groupBox_4.setObjectName("groupBox_4")
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_4)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox_4)
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_2)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.horizontalLayout_2.addLayout(self.focus_glo)
+ self.verticalLayout_5.addWidget(self.groupBox_2)
+ self.groupBox_6 = QtWidgets.QGroupBox(self.groupBox_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_6.sizePolicy().hasHeightForWidth())
+ self.groupBox_6.setSizePolicy(sizePolicy)
+ self.groupBox_6.setObjectName("groupBox_6")
+ self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.groupBox_6)
+ self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+ self.groupBox_7 = QtWidgets.QGroupBox(self.groupBox_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
+ self.groupBox_7.setSizePolicy(sizePolicy)
+ self.groupBox_7.setMaximumSize(QtCore.QSize(500, 500))
+ self.groupBox_7.setObjectName("groupBox_7")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.verticalLayout_6 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_6.setObjectName("verticalLayout_6")
+ self.label_3 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout_6.addWidget(self.label_3)
+ self.focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.focus_bt.setObjectName("focus_bt")
+ self.verticalLayout_6.addWidget(self.focus_bt)
+ self.exposureTime_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.exposureTime_bt.setObjectName("exposureTime_bt")
+ self.verticalLayout_6.addWidget(self.exposureTime_bt)
+ self.label_5 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_5.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_5.setObjectName("label_5")
+ self.verticalLayout_6.addWidget(self.label_5)
+ self.wb_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.wb_bt.setObjectName("wb_bt")
+ self.verticalLayout_6.addWidget(self.wb_bt)
+ self.label_2 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout_6.addWidget(self.label_2)
+ self.record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.record_bt.setObjectName("record_bt")
+ self.verticalLayout_6.addWidget(self.record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_6)
+ self.verticalLayout_8 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_8.setObjectName("verticalLayout_8")
+ self.framerate_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.verticalLayout_8.addWidget(self.framerate_le)
+ self.stop_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.stop_focus_bt.setObjectName("stop_focus_bt")
+ self.verticalLayout_8.addWidget(self.stop_focus_bt)
+ self.exposureTime_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.exposureTime_le.setObjectName("exposureTime_le")
+ self.verticalLayout_8.addWidget(self.exposureTime_le)
+ self.gain_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.gain_le.setObjectName("gain_le")
+ self.verticalLayout_8.addWidget(self.gain_le)
+ self.dc_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.dc_bt.setObjectName("dc_bt")
+ self.verticalLayout_8.addWidget(self.dc_bt)
+ self.framenumber_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.verticalLayout_8.addWidget(self.framenumber_le)
+ self.motor_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.motor_bt.setObjectName("motor_bt")
+ self.verticalLayout_8.addWidget(self.motor_bt)
+ self.stop_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.stop_record_bt.setObjectName("stop_record_bt")
+ self.verticalLayout_8.addWidget(self.stop_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_8)
+ self.horizontalLayout_5.addWidget(self.groupBox_7)
+ spacerItem2 = QtWidgets.QSpacerItem(261, 17, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_5.addItem(spacerItem2)
+ self.verticalLayout_5.addWidget(self.groupBox_6)
+ self.verticalLayout_7.addWidget(self.splitter)
+
+ self.retranslateUi(image_Window)
+ QtCore.QMetaObject.connectSlotsByName(image_Window)
+
+ def retranslateUi(self, image_Window):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window.setWindowTitle(_translate("image_Window", "影像窗口"))
+ self.groupBox_5.setTitle(_translate("image_Window", "GroupBox"))
+ self.label.setText(_translate("image_Window", "保存路径"))
+ self.label_4.setText(_translate("image_Window", "文件名"))
+ self.filepath_bt.setText(_translate("image_Window", "浏览"))
+ self.save_bt.setText(_translate("image_Window", "保存"))
+ self.groupBox_3.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox.setTitle(_translate("image_Window", "图像"))
+ self.groupBox_4.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_2.setTitle(_translate("image_Window", "光谱"))
+ self.groupBox_6.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_7.setTitle(_translate("image_Window", "GroupBox"))
+ self.label_3.setText(_translate("image_Window", "帧率"))
+ self.focus_bt.setText(_translate("image_Window", "调焦"))
+ self.exposureTime_bt.setText(_translate("image_Window", "曝光"))
+ self.label_5.setText(_translate("image_Window", "gain"))
+ self.wb_bt.setText(_translate("image_Window", "白板"))
+ self.label_2.setText(_translate("image_Window", "帧数"))
+ self.record_bt.setText(_translate("image_Window", "采集"))
+ self.stop_focus_bt.setText(_translate("image_Window", "停止调焦"))
+ self.dc_bt.setText(_translate("image_Window", "暗电流"))
+ self.motor_bt.setText(_translate("image_Window", "马达"))
+ self.stop_record_bt.setText(_translate("image_Window", "停止采集"))
diff --git a/record_system_v21/image_Window.ui b/record_system_v21/image_Window.ui
new file mode 100644
index 0000000..c2133b3
--- /dev/null
+++ b/record_system_v21/image_Window.ui
@@ -0,0 +1,377 @@
+
+
+ image_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 1181
+ 683
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
-
+
+
+ 保存路径
+
+
+
+ -
+
+
+ 文件名
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ 浏览
+
+
+
+ -
+
+
+ 保存
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 2000
+ 16777215
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 图像
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 8777215
+ 100
+
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+ -
+
+
+ 光谱
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 500
+ 500
+
+
+
+ GroupBox
+
+
+
-
+
+
-
+
+
+ 帧率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 调焦
+
+
+
+ -
+
+
+ 曝光
+
+
+
+ -
+
+
+ gain
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 白板
+
+
+
+ -
+
+
+ 帧数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ -
+
+
+ 停止调焦
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ -
+
+
+ 马达
+
+
+
+ -
+
+
+ 停止采集
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 261
+ 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v21/spectral_Window.py b/record_system_v21/spectral_Window.py
new file mode 100644
index 0000000..749f060
--- /dev/null
+++ b/record_system_v21/spectral_Window.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window(object):
+ def setupUi(self, spectral_Window):
+ spectral_Window.setObjectName("spectral_Window")
+ spectral_Window.resize(792, 523)
+ self.label = QtWidgets.QLabel(spectral_Window)
+ self.label.setGeometry(QtCore.QRect(54, 10, 51, 20))
+ self.label.setObjectName("label")
+ self.filepath_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filepath_le.setGeometry(QtCore.QRect(131, 10, 261, 21))
+ self.filepath_le.setObjectName("filepath_le")
+ self.label_2 = QtWidgets.QLabel(spectral_Window)
+ self.label_2.setGeometry(QtCore.QRect(54, 40, 41, 20))
+ self.label_2.setObjectName("label_2")
+ self.filename_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filename_le.setGeometry(QtCore.QRect(131, 40, 261, 21))
+ self.filename_le.setObjectName("filename_le")
+ self.filepath_bt = QtWidgets.QPushButton(spectral_Window)
+ self.filepath_bt.setGeometry(QtCore.QRect(401, 10, 71, 21))
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.statu_tb = QtWidgets.QTextBrowser(spectral_Window)
+ self.statu_tb.setGeometry(QtCore.QRect(611, 210, 161, 301))
+ self.statu_tb.setObjectName("statu_tb")
+ self.tabWidget = QtWidgets.QTabWidget(spectral_Window)
+ self.tabWidget.setGeometry(QtCore.QRect(10, 70, 591, 441))
+ self.tabWidget.setObjectName("tabWidget")
+ self.tab = QtWidgets.QWidget()
+ self.tab.setObjectName("tab")
+ self.gridLayoutWidget = QtWidgets.QWidget(self.tab)
+ self.gridLayoutWidget.setGeometry(QtCore.QRect(0, 0, 581, 411))
+ self.gridLayoutWidget.setObjectName("gridLayoutWidget")
+ self.spe_glo = QtWidgets.QGridLayout(self.gridLayoutWidget)
+ self.spe_glo.setContentsMargins(0, 0, 0, 0)
+ self.spe_glo.setObjectName("spe_glo")
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_2 = QtWidgets.QWidget()
+ self.tab_2.setObjectName("tab_2")
+ self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab_2)
+ self.gridLayoutWidget_2.setGeometry(QtCore.QRect(-1, -1, 581, 411))
+ self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
+ self.align_glo = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
+ self.align_glo.setContentsMargins(0, 0, 0, 0)
+ self.align_glo.setObjectName("align_glo")
+ self.tabWidget.addTab(self.tab_2, "")
+ self.layoutWidget = QtWidgets.QWidget(spectral_Window)
+ self.layoutWidget.setGeometry(QtCore.QRect(610, 90, 195, 135))
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.align_bt.setObjectName("align_bt")
+ self.gridLayout.addWidget(self.align_bt, 0, 0, 1, 1)
+ self.stop_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.stop_align_bt.setObjectName("stop_align_bt")
+ self.gridLayout.addWidget(self.stop_align_bt, 0, 1, 1, 1)
+ self.wb_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.wb_bt.setObjectName("wb_bt")
+ self.gridLayout.addWidget(self.wb_bt, 1, 0, 1, 2)
+ self.dc_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.dc_bt.setObjectName("dc_bt")
+ self.gridLayout.addWidget(self.dc_bt, 2, 0, 1, 2)
+ self.record_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.record_bt.setObjectName("record_bt")
+ self.gridLayout.addWidget(self.record_bt, 3, 0, 1, 2)
+
+ self.retranslateUi(spectral_Window)
+ self.tabWidget.setCurrentIndex(0)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window)
+
+ def retranslateUi(self, spectral_Window):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window.setWindowTitle(_translate("spectral_Window", "光谱窗口"))
+ self.label.setText(_translate("spectral_Window", "保存路径"))
+ self.label_2.setText(_translate("spectral_Window", "文件名"))
+ self.filepath_bt.setText(_translate("spectral_Window", "浏览"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("spectral_Window", "spe"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("spectral_Window", "align"))
+ self.align_bt.setText(_translate("spectral_Window", "align"))
+ self.stop_align_bt.setText(_translate("spectral_Window", "stop align"))
+ self.wb_bt.setText(_translate("spectral_Window", "曝光/白板"))
+ self.dc_bt.setText(_translate("spectral_Window", "暗电流"))
+ self.record_bt.setText(_translate("spectral_Window", "采集"))
diff --git a/record_system_v21/spectral_Window.ui b/record_system_v21/spectral_Window.ui
new file mode 100644
index 0000000..f2641b7
--- /dev/null
+++ b/record_system_v21/spectral_Window.ui
@@ -0,0 +1,180 @@
+
+
+ spectral_Window
+
+
+
+ 0
+ 0
+ 792
+ 523
+
+
+
+ 光谱窗口
+
+
+
+
+ 54
+ 10
+ 51
+ 20
+
+
+
+ 保存路径
+
+
+
+
+
+ 131
+ 10
+ 261
+ 21
+
+
+
+
+
+
+ 54
+ 40
+ 41
+ 20
+
+
+
+ 文件名
+
+
+
+
+
+ 131
+ 40
+ 261
+ 21
+
+
+
+
+
+
+ 401
+ 10
+ 71
+ 21
+
+
+
+ 浏览
+
+
+
+
+
+ 611
+ 210
+ 161
+ 301
+
+
+
+
+
+
+ 10
+ 70
+ 591
+ 441
+
+
+
+ 0
+
+
+
+ spe
+
+
+
+
+ 0
+ 0
+ 581
+ 411
+
+
+
+
+
+
+
+ align
+
+
+
+
+ -1
+ -1
+ 581
+ 411
+
+
+
+
+
+
+
+
+
+ 610
+ 90
+ 195
+ 135
+
+
+
+ -
+
+
+ align
+
+
+
+ -
+
+
+ stop align
+
+
+
+ -
+
+
+ 曝光/白板
+
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v22/2record_system_v2.2.py b/record_system_v22/2record_system_v2.2.py
new file mode 100644
index 0000000..87f3eaf
--- /dev/null
+++ b/record_system_v22/2record_system_v2.2.py
@@ -0,0 +1,1203 @@
+'''
+在2record system_v2.1的基础上新增功能:
+1、使用多线程采集数据,解决数据采集过程中界面卡死的情况
+2、实现了自动曝光
+3、实现了arcus马达控制
+4、通过共享变量来实现影像边采集边刷新
+'''
+
+from ximea import xiapi
+import numpy as np
+import os, sys, functools, re, shutil, traceback
+import subprocess
+
+
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog
+# from PyQt5.QtCore import pyqtSignal, QObject, QRunnable, QThreadPool
+from PyQt5.QtCore import *
+from enter_window import *
+from image_Window import *
+from spectral_Window import *
+from arcus_control_ui import *
+
+import cv2
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.figure import Figure
+import matplotlib.pyplot as plt
+
+
+
+class ArcusWindow(QMainWindow, Ui_arcus_ui):
+ def __init__(self, parent=None):
+ super(ArcusWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ self.left_btn.pressed.connect(self.leftMove)
+ self.left_btn.released.connect(self.stop)
+ self.right_btn.pressed.connect(self.rightMove)
+ self.right_btn.released.connect(self.stop)
+
+
+ # self.speed_lineEdit.setText(self.arc.write('HSPD'))
+ self.speed_lineEdit.textEdited.connect(self.change_speed)
+
+
+ def leftMove(self):
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J-'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('左移ok!')
+
+ def rightMove(self):
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ print(output)
+ # print(error)
+ print('右移ok!')
+
+ def change_speed(self):
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py HSPD=' + str(self.speed_lineEdit.text())
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('改变速度ok!')
+
+ def stop(self):
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py STOP'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('停止ok!')
+
+
+#EnterWindow
+# 主窗口
+class EnterWindow(QMainWindow, Ui_enter_Window):
+ def __init__(self, parent=None):
+ super(EnterWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ # 在刚打开软件在本窗口显示相机状态(是否打开)
+ self.c = Communicate()
+ self.c.openinfo.connect(self.printCamInfo)
+ # self.end_Btn.clicked.connect(self.end_event) # 绑定登陆函数
+ # self.exit_Btn.clicked.connect(sys.exit)
+
+ def printCamInfo(self):
+ self.camstatus_tb.append('相机已打开!')
+
+# 主窗口信号类
+class Communicate(QObject):
+ openinfo = pyqtSignal()
+ plotsignal = pyqtSignal()
+
+
+#ImageWindow
+# 图像窗口
+class ImageWindow(QDialog, Ui_image_Window):
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(ImageWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+
+
+
+ # 采集影像时,边采集边刷新显示
+ # self.plotsignal = pyqtSignal() # 直接这样建立信号执行时会报错
+ self.plotsignal = Communicate()
+ self.plotsignal.plotsignal.connect(self.plotimg)
+
+ #建立进程池
+ # https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ #初始化窗口中的值
+ self.framenumber_le.setText(str(camera_operation.framenumber_input))
+ self.framerate_le.setText(str(camera_operation.framerate_input))
+ self.exposureTime_le.setText(str(camera_operation.exposureTime_input))
+ self.gain_le.setText(str(camera_operation.gain_input))
+ self.filename_le.setText('test')
+ self.filepath_le.setText(os.getcwd())
+
+
+ #手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.exposureTime_le.textEdited.connect(self.onchange2)
+ self.exposureTime_le.textChanged.connect(self.onchange)# 将 自动曝光返回到QLineEdit中的值 写入到camera_operation.exposureTime_input
+ self.gain_le.textEdited.connect(self.onchange2)
+ self.gain_le.textChanged.connect(self.onchange)# 将 自动曝光返回到QLineEdit中的值 写入到camera_operation.gain_input
+ self.framerate_le.textEdited.connect(self.onchange2)
+ self.filename_le.textEdited.connect(self.onchange)
+ self.filepath_bt.clicked.connect(self.directory_select)
+ self.framenumber_le.textEdited.connect(self.onchange)
+ self.filepath_le.textEdited.connect(self.onchange)
+
+ # 显示影像和调焦
+ self.myImageFigure = MyImageFigure()
+ self.image_glo.addWidget(self.myImageFigure)
+ self.myFocusFigure = MySpectralFigureFocus()
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ #操作光谱仪
+ ## 注释的代码没有使用多线程,所以会造成一采集数据界面就卡死的情况
+ # self.focus_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.dc_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.save_bt.clicked.connect(camera_operation.savedata)
+ self.exposureTime_bt.clicked.connect(self.autoExposure)
+ self.focus_bt.clicked.connect(self.run)
+ # 停止调焦和采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.stop_focus_bt.clicked.connect(self.stop_focus)
+ self.stop_record_bt.clicked.connect(self.stop_record)
+ self.dc_bt.clicked.connect(self.run)
+ self.wb_bt.clicked.connect(self.run)
+ self.record_bt.clicked.connect(self.run)
+ self.save_bt.clicked.connect(self.save_image)
+
+ def plotimg(self):
+ worker = Worker(camera_operation.plotimg)
+ self.threadpool.start(worker)
+
+ def stop_focus(self):
+ camera_operation.focus = False
+
+ def stop_record(self):
+ camera_operation.record = False
+
+ # 调焦、采集暗电流、采集白板、采集影像 都通过此函数
+ def run(self):
+ qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if qt_sender == 'focus_bt':
+ self.statu_tb.append('调焦...')
+ elif qt_sender == 'dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ elif qt_sender == 'wb_bt':
+ self.statu_tb.append('采集白板...')
+ elif qt_sender == 'record_bt':
+ self.statu_tb.append('采集影像...')
+
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(camera_operation.start_AcquireData, camera, qt_sender)
+ self.threadpool.start(worker)
+
+ # 操作状态显示 + 为相机设置exposure和gain
+ if qt_sender == 'focus_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('调焦成功!'))
+ elif qt_sender == 'dc_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('采集暗电流成功!'))
+ elif qt_sender == 'wb_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('采集白板成功!'))
+ elif qt_sender == 'record_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('采集影像成功!'))
+
+ # 获取曝光参数:exposure和gain;并将值返回显示到界面中对应的QLineEdit中
+ def autoExposure(self):
+ qt_sender = self.sender().objectName()
+ self.statu_tb.append('自动曝光...')
+ worker = Worker(camera_operation.start_AcquireData, camera, qt_sender)
+ # 曝光参数的设置过程:
+ # (1)曝光参数返回到界面中的QLineEdit;
+ # (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ # (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ # 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ worker.signals.result.connect(self.changeTXT_QLineEdit)
+ worker.signals.finished.connect(self.set_exposure) #也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+
+ self.threadpool.start(worker)
+
+ # 将自动曝光返回值写入到界面中的QLineEdit
+ def changeTXT_QLineEdit(self, result):
+ self.exposureTime_le.setText(str(result[0]))
+ self.gain_le.setText(str(result[1]))
+ if result[2] == 1:
+ QMessageBox.information(self, '曝光提示', '光线不足,曝光时间已设置为最大!', QMessageBox.Yes)
+ camera_operation.autoexposure_feedback = 0
+
+ # 设置曝光参数:exposure和gain
+ def set_exposure(self):
+ self.statu_tb.append('自动曝光成功!')
+ camera_operation.set_exposureTime(camera)
+
+ def save_image(self):
+ # 操作状态显示
+ self.statu_tb.append('保存影像...')
+
+ worker = Worker(camera_operation.savedata)
+ self.threadpool.start(worker)
+
+ # 操作状态显示
+ worker.signals.finished.connect(lambda: self.statu_tb.append('保存影像成功!'))
+
+ # (textChanged)将 自动曝光返回到QLineEdit中的值 写入camera_operation类对应的变量中
+ def onchange(self):
+ camera_operation.framenumber_input = self.framenumber_le.text()
+ camera_operation.fn = self.filename_le.text()
+ camera_operation.fp = self.filepath_le.text()
+ camera_operation.rgb = np.ones((3, int(camera_operation.framenumber_input), int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial)))
+
+ # 这两个不是手动改变,是自动曝光返回的值
+ camera_operation.gain_input = self.gain_le.text()
+ camera_operation.exposureTime_input = self.exposureTime_le.text()
+
+ # 手动修改(textEdited)界面中的值后,为相机重新设置如下参数:exposure, gain, framerate
+ def onchange2(self):
+ camera_operation.gain_input = self.gain_le.text()
+ camera_operation.exposureTime_input = self.exposureTime_le.text()
+ camera_operation.framerate_input = self.framerate_le.text()
+ camera_operation.set_exposureTime(camera)
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', '/home')
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.filepath_le.setText(dirpath)
+ camera_operation.fp = dirpath
+
+#SpectralWindow
+# 光谱窗口
+class SpectralWindow(QDialog, Ui_spectral_Window):
+ def __init__(self, parent=None):
+ super(SpectralWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化值
+ self.filename_le.setText('test')
+ self.filepath_le.setText(os.getcwd())
+
+ #手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filepath_bt.clicked.connect(self.directory_select)
+ self.filename_le.textEdited.connect(self.onchange)
+ self.filepath_le.textEdited.connect(self.onchange)
+
+
+ # 显示光谱和align
+ self.spectralFigure = MySpectralFigureSpectral()
+ self.spe_glo.addWidget(self.spectralFigure)
+ self.alignFigure = MyImageFigure()
+ self.align_glo.addWidget(self.alignFigure)
+
+ #操作光谱仪
+ # self.dc_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ self.wb_bt.clicked.connect(self.run) # 曝光 + 采集白板
+ self.align_bt.clicked.connect(self.run)
+ self.stop_align_bt.clicked.connect(self.stop_align) # 这个操作非常简单,耗时非常短,瞬间可回到event loop;所以不需要多线程
+ self.dc_bt.clicked.connect(self.run)
+ self.record_bt.clicked.connect(self.run)
+
+ def stop_align(self):
+ spectral_camera_operation.align = False
+
+ def run(self):
+ qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if qt_sender == 'wb_bt':
+ self.statu_tb.append('曝光/白板...')
+ elif qt_sender == 'align_bt':
+ self.statu_tb.append('align...')
+ elif qt_sender == 'dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ elif qt_sender == 'wb_bt':
+ self.statu_tb.append('采集白板...')
+ elif qt_sender == 'record_bt':
+ self.statu_tb.append('采集光谱...')
+
+
+ worker = Worker(spectral_camera_operation.start_AcquireData, camera, qt_sender)
+ self.threadpool.start(worker)
+
+
+ # 操作状态显示
+ if qt_sender == 'wb_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('曝光/白板成功!'))
+ elif qt_sender == 'align_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('align successfully!'))
+ elif qt_sender == 'dc_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('采集暗电流成功!'))
+ elif qt_sender == 'wb_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('采集白板成功!'))
+ elif qt_sender == 'record_bt':
+ worker.signals.finished.connect(lambda: self.statu_tb.append('采集光谱成功!'))
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ spectral_camera_operation.fn = self.filename_le.text()
+ spectral_camera_operation.fp = self.filepath_le.text()
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', '/home')
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.filepath_le.setText(dirpath)
+ spectral_camera_operation.fp = dirpath
+
+
+#MySpectralFigureFocus
+# 画图类,用于:画出采集到的光谱;调焦(影响模式调焦)
+class MySpectralFigureFocus(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ #第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ #第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MySpectralFigureFocus, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, spectral):
+ self.axes.clear()
+ self.axes.plot(spectral)
+
+
+#MySpectralFigureSpectral
+class MySpectralFigureSpectral(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MySpectralFigureSpectral, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ self.axes
+ #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, Wavelength, spectral):
+ self.axes.clear()
+ self.axes.plot(Wavelength, spectral)
+
+# 画图类,用于:画出采集到的图像;显示帧流(光谱模式对准光纤)
+class MyImageFigure(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MyImageFigure, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xticks([])
+ self.axes.set_yticks([])
+ # 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, frame):
+ self.axes.clear()
+ self.axes.set_xticks([])
+ self.axes.set_yticks([])
+ self.axes.imshow(frame)
+
+class WorkerSignals(QObject):
+ '''
+ Defines the signals available from a running worker thread.
+
+ Supported signals are:
+
+ finished
+ No data
+
+ error
+ `tuple` (exctype, value, traceback.format_exc() )
+
+ result
+ `object` data returned from processing, anything
+
+ progress
+ `int` indicating % progress
+
+ '''
+ finished = pyqtSignal()
+ error = pyqtSignal(tuple)
+ result = pyqtSignal(object)
+ progress = pyqtSignal(int)
+
+# https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+# 用于qt多线程:运行long-time task
+class Worker(QRunnable):
+ '''
+ Worker thread
+
+ Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
+
+ :param callback: The function callback to run on this worker thread. Supplied args and
+ kwargs will be passed through to the runner.
+ :type callback: function
+ :param args: Arguments to pass to the callback function
+ :param kwargs: Keywords to pass to the callback function
+
+ '''
+
+ def __init__(self, fn, *args, **kwargs):
+ super(Worker, self).__init__()
+
+ # Store constructor arguments (re-used for processing)
+ self.fn = fn
+ self.args = args
+ self.kwargs = kwargs
+ self.signals = WorkerSignals()
+
+ # Add the callback to our kwargs
+ # self.kwargs['progress_callback'] = self.signals.progress
+
+ @pyqtSlot()
+ def run(self):
+ '''
+ Initialise the runner function with passed args, kwargs.
+ '''
+
+ # Retrieve args/kwargs here; and fire processing using them
+
+ try:
+ result = self.fn(*self.args, **self.kwargs)
+ except:
+ traceback.print_exc()
+ exctype, value = sys.exc_info()[:2]
+ self.signals.error.emit((exctype, value, traceback.format_exc()))
+ else:
+ self.signals.result.emit(result) # Return the result of the processing
+ finally:
+ self.signals.finished.emit() # Done
+
+# 影像模式类:相关的函数和变量
+class camera_operation(object):
+
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1649
+
+ # 设置曝光时间和帧率
+ framerate_input = 10 #随便给个初始值(初始值要和framerate_le控件初始值一致),从image_window获取的手动输入的帧率
+ exposureTime_input = 18
+ gain_input = 0
+
+ @classmethod
+ def autoexposure(cls, cam, img):
+ cam.set_framerate(cls.framerate_input)
+
+
+ @classmethod
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposureTime(cls, cam):
+ # settings,cam.set_param("exposure",10000)
+ cam.set_framerate(int(cls.framerate_input))
+ cam.set_exposure(int(cls.exposureTime_input)) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(int(float(cls.gain_input))) #int('0.0')会报错,int(float('0.0'))不会报错
+ # print('Exposure was set to %i us' % cam.get_exposure())
+ # print('Framerate was set to %i FPS' % cam.get_framerate())
+ # ('Framerate: ' + str(cam.get_framerate()) + ' FPS')这样连接字符串会浪费内存
+ image_window_instance.statu_tb.append("%s%s%s" % ('Framerate: ', str(cam.get_framerate()), ' FPS'))
+ image_window_instance.statu_tb.append("%s%s%s" % ('Exposure: ', str(cam.get_exposure()), ' us'))
+ image_window_instance.statu_tb.append("%s%s%s" % ('Gain: ', str(cam.get_gain()), ' dB'))
+
+
+ # 开始采集数据
+ framenumber_input = 100 # 随便给个初始值(初始值要和framenumber_le控件初始值一致),从image_window获取的手动输入的帧数
+ image_dc = 1 # 随便给个初始值,此变量用于存储采集到的暗电流影像
+ image_wb = 1 # 随便给个初始值,此变量用于存储采集到的白板影像
+ focus = True # 用于停止调焦
+ record = True # 用于停止采集
+ img_datatype = 12 # 在头文件中确定影像数据类型
+ # bin相关设置
+ bin_spectral = 1 # 光谱bin
+ bin_spatial = 1 # 空间bin
+ k = np.arange(endRow - startRow)[0::bin_spectral]
+ l = np.arange(endColumn - startColumn)[0::bin_spatial]
+
+ rgb = np.zeros((3, int(framenumber_input), int((endColumn - startColumn) / bin_spatial)))
+
+ autoexposure_feedback = 0
+ @classmethod
+ def start_AcquireData(cls, cam, qt_sender): # qt_sender是指qt窗口中事件的发生者
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ # 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+ # 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype(' int(1 / int(cls.framerate_input) * 10**6):
+ cam.set_exposure(int(1 / int(cls.framerate_input) * 10**6))
+ cls.autoexposure_feedback = 1
+
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 如果点击“调焦”按钮
+ if qt_sender == 'focus_bt':
+ # cls.set_exposureTime(cam)
+
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not cls.focus:
+ cls.focus = True
+
+ cam.start_acquisition()
+
+ while cls.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_window_instance.myImageFigure.plot(image_container)
+ image_window_instance.myImageFigure.draw()
+ image_window_instance.myFocusFigure.plot(image_container[150, :])
+ image_window_instance.myFocusFigure.draw()
+
+ # 如果点击“白板”按钮,采集并保存白板影像到image_wb
+ if qt_sender == 'wb_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ cls.image_wb = image_container_bin
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'dc_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ cls.image_dc = image_container_bin
+
+ # 如果点击“采集”按钮,自动去除暗电流,并且转化成反射率
+ if qt_sender == 'record_bt':
+ frameCount = 1 # 统计采集的帧数,用于停止采集使用
+
+ # 当停止采集后,再次开始采集需要将cls.record的值从False变为True
+ if not cls.record:
+ cls.record = True
+
+ # 开始马达
+ try:
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR PX=0 EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+ except:
+ pass
+
+
+ # 开始采集数据 并且 将数据写入到硬盘中
+ cam.start_acquisition()
+ with open('corning410_test', 'wb') as f:
+
+ print('Starting data acquisition...')
+ startTime = datetime.datetime.now()
+
+ while cls.record:
+ cam.get_image(img) # get data and pass them from camera to img
+ # image_raw_numpy.dtype -> dtype(' maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+ else: # 对于彩色照片,需要先单独对每个波段拉伸
+ img_new = np.empty(img.shape)
+ for i in range(img.shape[2]):
+ low = np.percentile(img[:, :, i], lowPercentile)
+ up = np.percentile(img[:, :, i], highPercentile)
+
+ img_new[:, :, i] = minout + ((img[:, :, i] - low) / (up - low)) * (maxout - minout)
+ img_new[:, :, i][img_new[:, :, i] < minout] = minout
+ img_new[:, :, i][img_new[:, :, i] > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+
+ @classmethod
+ def close_camera(cls, cam):
+ # stop communication
+ cam.close_device()
+
+
+# 光谱模式类:相关的函数和变量
+class spectral_camera_operation(object):
+
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1650
+
+ # 开始采集数据
+ fp = os.getcwd() # 随便给个初始值(初始值要和filepath_le控件初始值一致),从spectral_window获取的手动输入的帧率
+ fn = 'test' # 随便给个初始值(初始值要和filename_le控件初始值一致),从spectral_window获取的手动输入的帧率
+
+ framenumber = 10 # 每条光谱为多少帧平均得到
+ spectral_container = np.empty((endRow - startRow, framenumber, endColumn - startColumn)).astype(np.float)
+ # spectral_container = np.empty((300, framenumber, 3)).astype(np.float64)
+
+ align = True # 用于对准光纤
+ image_dc = np.empty((endRow - startRow, endColumn - startColumn)) # 此变量用于存储采集到的暗电流,一帧
+ spectralNumber_wb = 1 # 每次采集的白板的光谱数
+ spectral_wb = np.empty((endRow - startRow, endColumn - startColumn)) # 此变量用于存储采集到的白板,一帧
+ spectral_wb_tmp = np.empty((endRow - startRow, framenumber, endColumn - startColumn)).astype(
+ np.float64) # 随便给个初始值,此变量用于存储采集到的白板影像,后面白板影像去除了暗电流后值赋给spectral_wb
+ spectralNumber = 10 # 每次采集目标物的光谱数
+ spectral = np.empty((endRow - startRow, spectralNumber)).astype(np.float) # 此ndarray用于存储采集到的目标物光谱,每一列为一个光谱
+
+ @classmethod
+ def start_AcquireData(cls, cam, qt_sender):
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ cam.set_imgdataformat('XI_RAW16')
+ # create instance of Image to store image data and metadata
+ img = xiapi.Image()
+
+ print('Starting data acquisition...')
+ starttime = datetime.datetime.now()
+
+
+ # 如果点击“曝光/白板”按钮:(1)先自动曝光;(2)然后在采集白板
+ if qt_sender == 'wb_bt':
+
+ # 自动曝光
+ cam.set_framerate(15)
+ cam.set_aeag_roi_offset_x(cls.startColumn)
+ cam.set_aeag_roi_offset_y(cls.startRow)
+ cam.set_aeag_roi_height(cls.endRow - cls.startRow)
+ cam.set_aeag_roi_width(cls.endColumn - cls.startColumn)
+ # cam.set_exp_priority(1) # Exposure priority (0.8 - exposure 80%, gain 20%).XI_PRM_EXP_PRIORITY
+ # cam.set_ae_max_limit(24000) # Maximum time (us) used for exposure in AEAG procedureXI_PRM_AE_MAX_LIMIT
+ # cam.set_ag_max_limit(12)
+ # cam.set_aeag_level(50) # Average intensity of output signal AEAG should achieve(in %)XI_PRM_AEAG_LEVEL
+ # 还有两个不知怎么用的参数:XI_PRM_GAIN_SELECTOR or "gain_selector"和XI_PRM_SHUTTER_TYPE or "shutter_type"
+ cam.enable_aeag()
+ cam.start_acquisition()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ cam.disable_aeag()
+
+ # 将自动曝光获得的exposure和gain写入到相机
+ cam.set_framerate(15)
+ cam.set_exposure(cam.get_exposure())
+ cam.set_gain(cam.get_gain())
+ spectral_window_instance.statu_tb.append('Exposure: ' + str(cam.get_exposure()) + ' us')
+ spectral_window_instance.statu_tb.append('Framerate: ' + str(cam.get_framerate()) + ' FPS')
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 开始采集白板数据,去除白板暗电流的操作放在采集暗电流时进行
+ cam.start_acquisition()
+ for j in range(cls.spectralNumber_wb):
+ for i in range(cls.framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow,
+ cls.startColumn:cls.endColumn]
+
+ # 去除白板暗电流的操作放在采集暗电流时进行
+ # cls.spectral_container没经过运算,传给cls.spectral_wb_tmp的是cls.spectral_container的内存地址
+ cls.spectral_wb_tmp = cls.spectral_container
+
+ # 存储原始白板影像
+ filename = cls.fp + '\\' + 'baiban'
+ with open(filename, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_wb_tmp[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+
+ # 如果点击暗“align”按钮
+ if qt_sender == 'align_bt':
+
+ if not cls.align:
+ cls.align = True
+
+ cam.start_acquisition()
+ while cls.align:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ spectral_window_instance.alignFigure.plot(image_raw_numpy)
+ spectral_window_instance.alignFigure.draw()
+
+ # 如果点击暗“暗电流”按钮
+ if qt_sender == 'dc_bt':
+ # 为cls.spectral_container新建立一个内存地址,以免改变cls.spectral_wb_tmp(传址)的值
+ cls.spectral_container = np.empty(
+ (cls.endRow - cls.startRow, cls.framenumber, cls.endColumn - cls.startColumn)).astype(np.float64)
+ cam.start_acquisition()
+ for i in range(cls.framenumber):#此循环为啥会改变649行的赋值的结果呢?怎么会执行那里的代码
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+
+ # 存储暗电流影像
+ filename1 = cls.fp + '\\' + 'dark'
+ with open(filename1, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename1, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # cls.spectral_container经过运算,传给cls.image_dc的不是cls.spectral_container的内存地址,是新运算结果的内存地址;相当于传值
+ cls.image_dc = cls.spectral_container.mean(axis=1) # 因为平均,cls.image_dc的数据类型为:dtype('float64')
+
+
+
+ # 去除白板暗电流
+ for i in range(cls.framenumber):
+ cls.spectral_wb_tmp[:, i, :] = cls.spectral_wb_tmp[:, i, :] - cls.image_dc
+
+
+ # 存储扣除暗电流的白板影像
+ filename2 = cls.fp + '\\' + 'baiban_rmdark'
+ with open(filename2, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_wb_tmp[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename2, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ cls.spectral_wb = cls.spectral_wb_tmp.mean(axis=1) # 因为平均,cls.spectral_wb的数据类型为:dtype('float64')
+
+
+ # 如果点击“采集”按钮,去除暗电流,转化成反射率,
+ if qt_sender == 'record_bt':
+ cam.start_acquisition()
+ for j in range(cls.spectralNumber):
+ for i in range(cls.framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ # 存储扣除暗电流前的目标物影像
+ if j == 1:
+ filename1 = cls.fp + '\\' + cls.fn
+ with open(filename1, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename1, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ for i in range(cls.framenumber): # (1)去除暗电流;(2)转反射率
+ cls.spectral_container[:, i, :] = (cls.spectral_container[:, i, :] - cls.image_dc) / cls.spectral_wb
+
+ # 存储目标物反射率影像
+ if j == 1:
+ filename2 = cls.fp + '\\' + cls.fn + '_ref'
+ with open(filename2, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename2, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # spectral_tmp = cls.spectral_container.sum(axis=1).sum(axis=1)
+ spectral_tmp = cls.spectral_container.mean(axis=1).mean(axis=1)
+
+ cls.spectral[:, j] = spectral_tmp
+
+
+ # 画出光谱
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+ wavelength = np.empty(cls.endRow - cls.startRow)
+ for i in range(cls.startRow, cls.endRow):
+ wavelength[i - cls.startRow] = calculate_wavelength(i)
+ spectral_window_instance.spectralFigure.plot(wavelength, spectral_tmp)
+ spectral_window_instance.spectralFigure.draw()
+
+
+ # 计算波长
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+ wavelength = np.empty(cls.endRow - cls.startRow)
+ for i in range(cls.startRow, cls.endRow):
+ wavelength[i - cls.startRow] = calculate_wavelength(i)
+ # 保存光谱为txt文件
+ cls.spectral = np.insert(cls.spectral, 0, wavelength, axis=1)
+ for i in range(cls.spectralNumber):
+ np.savetxt(cls.fp + '\\' + cls.fn + str(i) + '.txt', cls.spectral[:, [0, i + 1]], fmt='%f')
+
+
+ endtime = datetime.datetime.now()
+ print('光谱采集用时:%d' % (endtime - starttime).seconds)
+
+ # stop data acquisition
+ print('Stopping acquisition...')
+ cam.stop_acquisition()
+
+ @classmethod
+ def close_camera(cls, cam):
+ # stop communication
+ cam.close_device()
+
+
+# 打开相机
+def open_camera():
+ # create instance for first connected camera
+ cam = xiapi.Camera()
+
+ # start communication to open specific device, use: cam.open_device_by_SN('41305651')
+ print('Opening first camera...')
+ cam.open_device()
+
+ # 打开相机后,显示相机信息
+ print('SN: %s' % str(cam.get_device_sn(), encoding="utf-8"))
+ print('Device name: %s' % str(cam.get_device_name(), encoding="utf-8"))
+ print('Device name: %s' % str(cam.get_device_type(), encoding="utf-8"))
+ print('Instance path: %s' % str(cam.get_device_inst_path(),
+ encoding="utf-8")) # Returns device instance path in operating system.
+ print('Location path: %s' % str(cam.get_device_loc_path(), encoding="utf-8"))
+
+ print('Debug level: %s' % cam.get_debug_level())
+ print('Default number of threads per image processor: %d' % cam.get_proc_num_threads())
+ cam.set_proc_num_threads(8)
+ print('Current number of threads per image processor: %d' % cam.get_proc_num_threads())
+ print('Is horizontal flip enabled?, %s' % str(cam.is_horizontal_flip()))
+ print()
+
+ # This mode is supported by selected camera families: CB, MC, MT, MX
+ cam.set_acq_timing_mode('XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ mode_used = cam.get_acq_timing_mode()
+ if mode_used == 'XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT':
+ print('Mode is XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ else:
+ print('Mode is not XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ sys.exit()
+
+ return cam
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+ camera = open_camera()
+
+
+ #实例化4个窗口
+ enter_window_instance = EnterWindow()
+ image_window_instance = ImageWindow()
+ image_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ spectral_window_instance = SpectralWindow()
+ spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+
+ arcus_window_instance = ArcusWindow()
+
+ enter_window_instance.c.openinfo.emit()
+
+
+ #从主窗口弹出影像窗口和光谱窗口
+ enter_window_instance.image_mode_bt.clicked.connect(image_window_instance.show)
+ enter_window_instance.spectral_mode_bt.clicked.connect(spectral_window_instance.show)
+ image_window_instance.motor_bt.clicked.connect(arcus_window_instance.show)
+
+
+ enter_window_instance.show()
+ sys.exit(app.exec_())
diff --git a/record_system_v22/arcus_control_ui.py b/record_system_v22/arcus_control_ui.py
new file mode 100644
index 0000000..640777f
--- /dev/null
+++ b/record_system_v22/arcus_control_ui.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'arcus_control_ui.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_arcus_ui(object):
+ def setupUi(self, arcus_ui):
+ arcus_ui.setObjectName("arcus_ui")
+ arcus_ui.resize(354, 171)
+ self.centralwidget = QtWidgets.QWidget(arcus_ui)
+ self.centralwidget.setObjectName("centralwidget")
+ self.left_btn = QtWidgets.QPushButton(self.centralwidget)
+ self.left_btn.setGeometry(QtCore.QRect(100, 90, 61, 21))
+ self.left_btn.setObjectName("left_btn")
+ self.right_btn = QtWidgets.QPushButton(self.centralwidget)
+ self.right_btn.setGeometry(QtCore.QRect(170, 90, 61, 23))
+ self.right_btn.setObjectName("right_btn")
+ self.speed_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
+ self.speed_lineEdit.setGeometry(QtCore.QRect(101, 10, 131, 20))
+ self.speed_lineEdit.setObjectName("speed_lineEdit")
+ self.speed_ScrollBar = QtWidgets.QScrollBar(self.centralwidget)
+ self.speed_ScrollBar.setGeometry(QtCore.QRect(100, 40, 131, 20))
+ self.speed_ScrollBar.setOrientation(QtCore.Qt.Horizontal)
+ self.speed_ScrollBar.setObjectName("speed_ScrollBar")
+ arcus_ui.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(arcus_ui)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 354, 23))
+ self.menubar.setObjectName("menubar")
+ arcus_ui.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(arcus_ui)
+ self.statusbar.setObjectName("statusbar")
+ arcus_ui.setStatusBar(self.statusbar)
+
+ self.retranslateUi(arcus_ui)
+ QtCore.QMetaObject.connectSlotsByName(arcus_ui)
+
+ def retranslateUi(self, arcus_ui):
+ _translate = QtCore.QCoreApplication.translate
+ arcus_ui.setWindowTitle(_translate("arcus_ui", "MainWindow"))
+ self.left_btn.setText(_translate("arcus_ui", "左"))
+ self.right_btn.setText(_translate("arcus_ui", "右"))
diff --git a/record_system_v22/arcus_control_ui.ui b/record_system_v22/arcus_control_ui.ui
new file mode 100644
index 0000000..b494281
--- /dev/null
+++ b/record_system_v22/arcus_control_ui.ui
@@ -0,0 +1,81 @@
+
+
+ arcus_ui
+
+
+
+ 0
+ 0
+ 354
+ 171
+
+
+
+ MainWindow
+
+
+
+
+
+ 100
+ 90
+ 61
+ 21
+
+
+
+ 左
+
+
+
+
+
+ 170
+ 90
+ 61
+ 23
+
+
+
+ 右
+
+
+
+
+
+ 101
+ 10
+ 131
+ 20
+
+
+
+
+
+
+ 100
+ 40
+ 131
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v22/enter_window.py b/record_system_v22/enter_window.py
new file mode 100644
index 0000000..9f5f1cd
--- /dev/null
+++ b/record_system_v22/enter_window.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'enter_window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_enter_Window(object):
+ def setupUi(self, enter_Window):
+ enter_Window.setObjectName("enter_Window")
+ enter_Window.resize(651, 474)
+ self.centralwidget = QtWidgets.QWidget(enter_Window)
+ self.centralwidget.setObjectName("centralwidget")
+ self.image_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.image_mode_bt.setGeometry(QtCore.QRect(200, 180, 111, 51))
+ self.image_mode_bt.setObjectName("image_mode_bt")
+ self.spectral_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.spectral_mode_bt.setGeometry(QtCore.QRect(360, 180, 111, 51))
+ self.spectral_mode_bt.setObjectName("spectral_mode_bt")
+ self.camstatus_tb = QtWidgets.QTextBrowser(self.centralwidget)
+ self.camstatus_tb.setGeometry(QtCore.QRect(200, 240, 271, 81))
+ self.camstatus_tb.setObjectName("camstatus_tb")
+ enter_Window.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(enter_Window)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 651, 26))
+ self.menubar.setObjectName("menubar")
+ enter_Window.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(enter_Window)
+ self.statusbar.setObjectName("statusbar")
+ enter_Window.setStatusBar(self.statusbar)
+ self.actionwew_e = QtWidgets.QAction(enter_Window)
+ self.actionwew_e.setObjectName("actionwew_e")
+
+ self.retranslateUi(enter_Window)
+ QtCore.QMetaObject.connectSlotsByName(enter_Window)
+
+ def retranslateUi(self, enter_Window):
+ _translate = QtCore.QCoreApplication.translate
+ enter_Window.setWindowTitle(_translate("enter_Window", "主窗口"))
+ self.image_mode_bt.setText(_translate("enter_Window", "影像模式"))
+ self.spectral_mode_bt.setText(_translate("enter_Window", "光谱模式"))
+ self.actionwew_e.setText(_translate("enter_Window", "wew e"))
diff --git a/record_system_v22/enter_window.ui b/record_system_v22/enter_window.ui
new file mode 100644
index 0000000..4c39418
--- /dev/null
+++ b/record_system_v22/enter_window.ui
@@ -0,0 +1,73 @@
+
+
+ enter_Window
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+
+
+ 200
+ 180
+ 111
+ 51
+
+
+
+ 影像模式
+
+
+
+
+
+ 360
+ 180
+ 111
+ 51
+
+
+
+ 光谱模式
+
+
+
+
+
+ 200
+ 240
+ 271
+ 81
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v22/image_Window.py b/record_system_v22/image_Window.py
new file mode 100644
index 0000000..53dc349
--- /dev/null
+++ b/record_system_v22/image_Window.py
@@ -0,0 +1,231 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window(object):
+ def setupUi(self, image_Window):
+ image_Window.setObjectName("image_Window")
+ image_Window.setEnabled(True)
+ image_Window.resize(1181, 683)
+ image_Window.setMouseTracking(False)
+ image_Window.setAutoFillBackground(False)
+ image_Window.setSizeGripEnabled(False)
+ image_Window.setModal(False)
+ self.verticalLayout_7 = QtWidgets.QVBoxLayout(image_Window)
+ self.verticalLayout_7.setObjectName("verticalLayout_7")
+ self.groupBox_5 = QtWidgets.QGroupBox(image_Window)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
+ self.groupBox_5.setSizePolicy(sizePolicy)
+ self.groupBox_5.setObjectName("groupBox_5")
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.groupBox_5)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem)
+ self.splitter_3 = QtWidgets.QSplitter(self.groupBox_5)
+ self.splitter_3.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter_3.setObjectName("splitter_3")
+ self.layoutWidget = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(self.layoutWidget)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.label_4 = QtWidgets.QLabel(self.layoutWidget)
+ self.label_4.setObjectName("label_4")
+ self.verticalLayout.addWidget(self.label_4)
+ self.layoutWidget1 = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget1.setObjectName("layoutWidget1")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget1)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.filepath_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filepath_le.setObjectName("filepath_le")
+ self.verticalLayout_2.addWidget(self.filepath_le)
+ self.filename_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filename_le.setObjectName("filename_le")
+ self.verticalLayout_2.addWidget(self.filename_le)
+ self.layoutWidget2 = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget2.setObjectName("layoutWidget2")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.layoutWidget2)
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.filepath_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.verticalLayout_3.addWidget(self.filepath_bt)
+ self.save_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout_3.addWidget(self.save_bt)
+ self.horizontalLayout_4.addWidget(self.splitter_3)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem1)
+ self.verticalLayout_7.addWidget(self.groupBox_5)
+ self.splitter = QtWidgets.QSplitter(image_Window)
+ self.splitter.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter.setObjectName("splitter")
+ self.groupBox_3 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth())
+ self.groupBox_3.setSizePolicy(sizePolicy)
+ self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0))
+ self.groupBox_3.setMaximumSize(QtCore.QSize(2000, 16777215))
+ self.groupBox_3.setObjectName("groupBox_3")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_3)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.groupBox = QtWidgets.QGroupBox(self.groupBox_3)
+ self.groupBox.setObjectName("groupBox")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.horizontalLayout.addLayout(self.image_glo)
+ self.verticalLayout_4.addWidget(self.groupBox)
+ self.statu_tb = QtWidgets.QTextBrowser(self.groupBox_3)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.statu_tb.sizePolicy().hasHeightForWidth())
+ self.statu_tb.setSizePolicy(sizePolicy)
+ self.statu_tb.setMaximumSize(QtCore.QSize(8777215, 100))
+ self.statu_tb.setReadOnly(True)
+ self.statu_tb.setObjectName("statu_tb")
+ self.verticalLayout_4.addWidget(self.statu_tb)
+ self.groupBox_4 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_4.sizePolicy().hasHeightForWidth())
+ self.groupBox_4.setSizePolicy(sizePolicy)
+ self.groupBox_4.setObjectName("groupBox_4")
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_4)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox_4)
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_2)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.horizontalLayout_2.addLayout(self.focus_glo)
+ self.verticalLayout_5.addWidget(self.groupBox_2)
+ self.groupBox_6 = QtWidgets.QGroupBox(self.groupBox_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_6.sizePolicy().hasHeightForWidth())
+ self.groupBox_6.setSizePolicy(sizePolicy)
+ self.groupBox_6.setObjectName("groupBox_6")
+ self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.groupBox_6)
+ self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+ self.groupBox_7 = QtWidgets.QGroupBox(self.groupBox_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
+ self.groupBox_7.setSizePolicy(sizePolicy)
+ self.groupBox_7.setMaximumSize(QtCore.QSize(500, 500))
+ self.groupBox_7.setObjectName("groupBox_7")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.verticalLayout_6 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_6.setObjectName("verticalLayout_6")
+ self.label_3 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout_6.addWidget(self.label_3)
+ self.focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.focus_bt.setObjectName("focus_bt")
+ self.verticalLayout_6.addWidget(self.focus_bt)
+ self.exposureTime_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.exposureTime_bt.setObjectName("exposureTime_bt")
+ self.verticalLayout_6.addWidget(self.exposureTime_bt)
+ self.label_5 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_5.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_5.setObjectName("label_5")
+ self.verticalLayout_6.addWidget(self.label_5)
+ self.wb_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.wb_bt.setObjectName("wb_bt")
+ self.verticalLayout_6.addWidget(self.wb_bt)
+ self.label_2 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout_6.addWidget(self.label_2)
+ self.record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.record_bt.setObjectName("record_bt")
+ self.verticalLayout_6.addWidget(self.record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_6)
+ self.verticalLayout_8 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_8.setObjectName("verticalLayout_8")
+ self.framerate_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.verticalLayout_8.addWidget(self.framerate_le)
+ self.stop_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.stop_focus_bt.setObjectName("stop_focus_bt")
+ self.verticalLayout_8.addWidget(self.stop_focus_bt)
+ self.exposureTime_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.exposureTime_le.setObjectName("exposureTime_le")
+ self.verticalLayout_8.addWidget(self.exposureTime_le)
+ self.gain_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.gain_le.setObjectName("gain_le")
+ self.verticalLayout_8.addWidget(self.gain_le)
+ self.dc_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.dc_bt.setObjectName("dc_bt")
+ self.verticalLayout_8.addWidget(self.dc_bt)
+ self.framenumber_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.verticalLayout_8.addWidget(self.framenumber_le)
+ self.motor_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.motor_bt.setObjectName("motor_bt")
+ self.verticalLayout_8.addWidget(self.motor_bt)
+ self.stop_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.stop_record_bt.setObjectName("stop_record_bt")
+ self.verticalLayout_8.addWidget(self.stop_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_8)
+ self.horizontalLayout_5.addWidget(self.groupBox_7)
+ spacerItem2 = QtWidgets.QSpacerItem(261, 17, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_5.addItem(spacerItem2)
+ self.verticalLayout_5.addWidget(self.groupBox_6)
+ self.verticalLayout_7.addWidget(self.splitter)
+
+ self.retranslateUi(image_Window)
+ QtCore.QMetaObject.connectSlotsByName(image_Window)
+
+ def retranslateUi(self, image_Window):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window.setWindowTitle(_translate("image_Window", "影像窗口"))
+ self.groupBox_5.setTitle(_translate("image_Window", "GroupBox"))
+ self.label.setText(_translate("image_Window", "保存路径"))
+ self.label_4.setText(_translate("image_Window", "文件名"))
+ self.filepath_bt.setText(_translate("image_Window", "浏览"))
+ self.save_bt.setText(_translate("image_Window", "保存"))
+ self.groupBox_3.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox.setTitle(_translate("image_Window", "图像"))
+ self.groupBox_4.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_2.setTitle(_translate("image_Window", "光谱"))
+ self.groupBox_6.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_7.setTitle(_translate("image_Window", "GroupBox"))
+ self.label_3.setText(_translate("image_Window", "帧率"))
+ self.focus_bt.setText(_translate("image_Window", "调焦"))
+ self.exposureTime_bt.setText(_translate("image_Window", "曝光"))
+ self.label_5.setText(_translate("image_Window", "gain"))
+ self.wb_bt.setText(_translate("image_Window", "白板"))
+ self.label_2.setText(_translate("image_Window", "帧数"))
+ self.record_bt.setText(_translate("image_Window", "采集"))
+ self.stop_focus_bt.setText(_translate("image_Window", "停止调焦"))
+ self.dc_bt.setText(_translate("image_Window", "暗电流"))
+ self.motor_bt.setText(_translate("image_Window", "马达"))
+ self.stop_record_bt.setText(_translate("image_Window", "停止采集"))
diff --git a/record_system_v22/image_Window.ui b/record_system_v22/image_Window.ui
new file mode 100644
index 0000000..c2133b3
--- /dev/null
+++ b/record_system_v22/image_Window.ui
@@ -0,0 +1,377 @@
+
+
+ image_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 1181
+ 683
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
-
+
+
+ 保存路径
+
+
+
+ -
+
+
+ 文件名
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ 浏览
+
+
+
+ -
+
+
+ 保存
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 2000
+ 16777215
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 图像
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 8777215
+ 100
+
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+ -
+
+
+ 光谱
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 500
+ 500
+
+
+
+ GroupBox
+
+
+
-
+
+
-
+
+
+ 帧率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 调焦
+
+
+
+ -
+
+
+ 曝光
+
+
+
+ -
+
+
+ gain
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 白板
+
+
+
+ -
+
+
+ 帧数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ -
+
+
+ 停止调焦
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ -
+
+
+ 马达
+
+
+
+ -
+
+
+ 停止采集
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 261
+ 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v22/spectral_Window.py b/record_system_v22/spectral_Window.py
new file mode 100644
index 0000000..749f060
--- /dev/null
+++ b/record_system_v22/spectral_Window.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window(object):
+ def setupUi(self, spectral_Window):
+ spectral_Window.setObjectName("spectral_Window")
+ spectral_Window.resize(792, 523)
+ self.label = QtWidgets.QLabel(spectral_Window)
+ self.label.setGeometry(QtCore.QRect(54, 10, 51, 20))
+ self.label.setObjectName("label")
+ self.filepath_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filepath_le.setGeometry(QtCore.QRect(131, 10, 261, 21))
+ self.filepath_le.setObjectName("filepath_le")
+ self.label_2 = QtWidgets.QLabel(spectral_Window)
+ self.label_2.setGeometry(QtCore.QRect(54, 40, 41, 20))
+ self.label_2.setObjectName("label_2")
+ self.filename_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filename_le.setGeometry(QtCore.QRect(131, 40, 261, 21))
+ self.filename_le.setObjectName("filename_le")
+ self.filepath_bt = QtWidgets.QPushButton(spectral_Window)
+ self.filepath_bt.setGeometry(QtCore.QRect(401, 10, 71, 21))
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.statu_tb = QtWidgets.QTextBrowser(spectral_Window)
+ self.statu_tb.setGeometry(QtCore.QRect(611, 210, 161, 301))
+ self.statu_tb.setObjectName("statu_tb")
+ self.tabWidget = QtWidgets.QTabWidget(spectral_Window)
+ self.tabWidget.setGeometry(QtCore.QRect(10, 70, 591, 441))
+ self.tabWidget.setObjectName("tabWidget")
+ self.tab = QtWidgets.QWidget()
+ self.tab.setObjectName("tab")
+ self.gridLayoutWidget = QtWidgets.QWidget(self.tab)
+ self.gridLayoutWidget.setGeometry(QtCore.QRect(0, 0, 581, 411))
+ self.gridLayoutWidget.setObjectName("gridLayoutWidget")
+ self.spe_glo = QtWidgets.QGridLayout(self.gridLayoutWidget)
+ self.spe_glo.setContentsMargins(0, 0, 0, 0)
+ self.spe_glo.setObjectName("spe_glo")
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_2 = QtWidgets.QWidget()
+ self.tab_2.setObjectName("tab_2")
+ self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab_2)
+ self.gridLayoutWidget_2.setGeometry(QtCore.QRect(-1, -1, 581, 411))
+ self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
+ self.align_glo = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
+ self.align_glo.setContentsMargins(0, 0, 0, 0)
+ self.align_glo.setObjectName("align_glo")
+ self.tabWidget.addTab(self.tab_2, "")
+ self.layoutWidget = QtWidgets.QWidget(spectral_Window)
+ self.layoutWidget.setGeometry(QtCore.QRect(610, 90, 195, 135))
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.align_bt.setObjectName("align_bt")
+ self.gridLayout.addWidget(self.align_bt, 0, 0, 1, 1)
+ self.stop_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.stop_align_bt.setObjectName("stop_align_bt")
+ self.gridLayout.addWidget(self.stop_align_bt, 0, 1, 1, 1)
+ self.wb_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.wb_bt.setObjectName("wb_bt")
+ self.gridLayout.addWidget(self.wb_bt, 1, 0, 1, 2)
+ self.dc_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.dc_bt.setObjectName("dc_bt")
+ self.gridLayout.addWidget(self.dc_bt, 2, 0, 1, 2)
+ self.record_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.record_bt.setObjectName("record_bt")
+ self.gridLayout.addWidget(self.record_bt, 3, 0, 1, 2)
+
+ self.retranslateUi(spectral_Window)
+ self.tabWidget.setCurrentIndex(0)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window)
+
+ def retranslateUi(self, spectral_Window):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window.setWindowTitle(_translate("spectral_Window", "光谱窗口"))
+ self.label.setText(_translate("spectral_Window", "保存路径"))
+ self.label_2.setText(_translate("spectral_Window", "文件名"))
+ self.filepath_bt.setText(_translate("spectral_Window", "浏览"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("spectral_Window", "spe"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("spectral_Window", "align"))
+ self.align_bt.setText(_translate("spectral_Window", "align"))
+ self.stop_align_bt.setText(_translate("spectral_Window", "stop align"))
+ self.wb_bt.setText(_translate("spectral_Window", "曝光/白板"))
+ self.dc_bt.setText(_translate("spectral_Window", "暗电流"))
+ self.record_bt.setText(_translate("spectral_Window", "采集"))
diff --git a/record_system_v22/spectral_Window.ui b/record_system_v22/spectral_Window.ui
new file mode 100644
index 0000000..f2641b7
--- /dev/null
+++ b/record_system_v22/spectral_Window.ui
@@ -0,0 +1,180 @@
+
+
+ spectral_Window
+
+
+
+ 0
+ 0
+ 792
+ 523
+
+
+
+ 光谱窗口
+
+
+
+
+ 54
+ 10
+ 51
+ 20
+
+
+
+ 保存路径
+
+
+
+
+
+ 131
+ 10
+ 261
+ 21
+
+
+
+
+
+
+ 54
+ 40
+ 41
+ 20
+
+
+
+ 文件名
+
+
+
+
+
+ 131
+ 40
+ 261
+ 21
+
+
+
+
+
+
+ 401
+ 10
+ 71
+ 21
+
+
+
+ 浏览
+
+
+
+
+
+ 611
+ 210
+ 161
+ 301
+
+
+
+
+
+
+ 10
+ 70
+ 591
+ 441
+
+
+
+ 0
+
+
+
+ spe
+
+
+
+
+ 0
+ 0
+ 581
+ 411
+
+
+
+
+
+
+
+ align
+
+
+
+
+ -1
+ -1
+ 581
+ 411
+
+
+
+
+
+
+
+
+
+ 610
+ 90
+ 195
+ 135
+
+
+
+ -
+
+
+ align
+
+
+
+ -
+
+
+ stop align
+
+
+
+ -
+
+
+ 曝光/白板
+
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v23/2record_system_v2.3.py b/record_system_v23/2record_system_v2.3.py
new file mode 100644
index 0000000..51cb85f
--- /dev/null
+++ b/record_system_v23/2record_system_v2.3.py
@@ -0,0 +1,1438 @@
+'''
+在2record system_v2.1的基础上新增功能
+1、使用多线程 + 多进程采集数据:解决同一个线程同时采集和bin降低帧率的问题
+ 1)多线程:自动曝光、调焦、采集暗电流、采集白板等耗时短的任务
+ 2)多进程:把数据采集(进程1将影像数据写入Queue)、bin和数据写入硬盘(进程2从Queue中读取数据)两个步骤分开
+
+ 遇见问题:最后发现使用多进程来采集数据是会出现内存被用完的情况,如果电脑内存不大,会出现软件死机的情况;这是因为
+ 进程1向Queue中写的速度太快,而进程2从Queue中读取的速度太慢导致的
+
+2、通过共享变量来实现影像边采集边刷新:因为多进程采集,没有解决这个问题
+'''
+
+from ximea import xiapi
+import numpy as np
+import sharedmem as shm
+import os, sys, functools, re, shutil, traceback
+
+
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog
+# from PyQt5.QtCore import pyqtSignal, QObject, QRunnable, QThreadPool
+from PyQt5.QtCore import *
+from enter_window import *
+from image_Window import *
+from spectral_Window import *
+
+import cv2
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.figure import Figure
+import matplotlib.pyplot as plt
+
+import multiprocessing
+from multiprocessing import Process, Queue
+
+
+# 主窗口
+class enter_window(QMainWindow, Ui_enter_Window):
+ def __init__(self, parent=None):
+ super(enter_window, self).__init__(parent)
+ self.setupUi(self)
+
+ # 在刚打开软件在本窗口显示相机状态(是否打开)
+ self.c = Communicate()
+ self.c.openinfo.connect(self.printCamInfo)
+ # self.end_Btn.clicked.connect(self.end_event) # 绑定登陆函数
+ # self.exit_Btn.clicked.connect(sys.exit)
+
+ def printCamInfo(self):
+ self.camstatus_tb.append('相机已打开!')
+
+# 主窗口信号类
+class Communicate(QObject):
+ openinfo = pyqtSignal()
+
+# 图像窗口
+class image_window(QDialog, Ui_image_Window):
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(image_window, self).__init__(parent)
+ self.setupUi(self)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 建立多进程共享变量,用于控制数据采集的停止和显示
+ self.share_state = multiprocessing.Manager().Value('c_bool', True)
+ # 思路来源:https://stackoverflow.com/questions/7894791/use-numpy-array-in-shared-memory-for-multiprocessing
+ self.rgb = np.ones(int(camera_operation.framenumber_input) * int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial)).astype(
+ np.float32)
+ self.share_r = multiprocessing.Array('f', self.rgb)
+ self.share_g = multiprocessing.Array('f', self.rgb)
+ self.share_b = multiprocessing.Array('f', self.rgb)
+
+ # 初始化窗口中的值
+ self.framenumber_le.setText(str(camera_operation.framenumber_input))
+ self.framerate_le.setText(str(camera_operation.framerate_input))
+ self.exposureTime_le.setText(str(camera_operation.exposureTime_input))
+ self.gain_le.setText(str(camera_operation.gain_input))
+ self.filename_le.setText('test')
+ self.filepath_le.setText(os.getcwd())
+
+ # 手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.filepath_bt.clicked.connect(self.directory_select)
+ self.exposureTime_le.textEdited.connect(self.onchange2)
+ self.gain_le.textEdited.connect(self.onchange2)
+ self.framerate_le.textEdited.connect(self.onchange2)
+ self.filename_le.textEdited.connect(self.onchange)
+ self.framenumber_le.textEdited.connect(self.onchange)
+ self.filepath_le.textEdited.connect(self.onchange)
+
+ # 显示影像和调焦
+ self.myImageFigure = MyImageFigure()
+ self.image_glo.addWidget(self.myImageFigure)
+ self.myFocusFigure = MySpectralFigure_focus()
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ #操作光谱仪
+ ## 注释的代码没有使用多线程,所以会造成一采集数据界面就卡死的情况
+ # self.focus_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.dc_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.save_bt.clicked.connect(camera_operation.savedata)
+ self.exposureTime_bt.clicked.connect(self.autoExposure_multithread)
+ self.focus_bt.clicked.connect(self.record_image_multithread)
+ # 停止调焦和采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.stop_focus_bt.clicked.connect(self.stop_focus)
+ self.stop_record_bt.clicked.connect(self.stop_record)
+ self.dc_bt.clicked.connect(self.record_image_multithread)
+ self.wb_bt.clicked.connect(self.record_image_multithread)
+ # self.record_bt.clicked.connect() ##########################################################################################
+ self.save_bt.clicked.connect(self.save_image)
+
+ # 多进程采集影像
+ self.workThread = WorkThread()
+ self.record_bt.clicked.connect(self.record_image_multiprocess)
+ self.workThread.sinOut.connect(self.record_finish) # 数据采集完成后会发射信号,然后进行画图
+
+ # 自动曝光获取参数:exposure和gain;并将值返回显示到界面中对应的QLineEdit中
+ def autoExposure_multithread(self):
+ # 当点击曝光按钮后,让这些按钮不能使用,当采集成功后再让这些按钮可以使用
+ self.record_bt.setEnabled(False)
+ self.focus_bt.setEnabled(False)
+ self.exposureTime_bt.setEnabled(False)
+ self.dc_bt.setEnabled(False)
+ self.wb_bt.setEnabled(False)
+ self.save_bt.setEnabled(False)
+
+ qt_sender = self.sender().objectName()
+ self.statu_tb.append('自动曝光...')
+ worker = Worker(camera_operation.start_AcquireData, qt_sender)
+ # 曝光参数的设置过程:
+ # (1)曝光参数返回到界面中的QLineEdit;
+ # (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ # 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ worker.signals.result.connect(self.changeTXT_QLineEdit)
+ worker.signals.finished.connect(
+ self.exposure_finish) # 也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+
+ self.threadpool.start(worker)
+
+ # 调焦、采集暗电流、采集白板 都通过此函数
+ def record_image_multithread(self):
+ qt_sender = self.sender().objectName()
+
+ # 当点击采集后,让这些按钮不能使用,当采集成功后再让这些按钮可以使用
+ self.record_bt.setEnabled(False)
+ self.focus_bt.setEnabled(False)
+ self.exposureTime_bt.setEnabled(False)
+ self.dc_bt.setEnabled(False)
+ self.wb_bt.setEnabled(False)
+ self.save_bt.setEnabled(False)
+
+ # 操作状态显示
+ if qt_sender == 'focus_bt':
+ self.statu_tb.append('调焦...')
+ elif qt_sender == 'dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ elif qt_sender == 'wb_bt':
+ self.statu_tb.append('采集白板...')
+
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(camera_operation.start_AcquireData, qt_sender)
+ self.threadpool.start(worker)
+
+ # 操作状态显示 + 为相机设置exposure和gain
+ if qt_sender == 'focus_bt':
+ # worker.signals.finished.connect(lambda: self.statu_tb.append('调焦成功!'))
+ worker.signals.finished.connect(self.focus_finish)
+ elif qt_sender == 'dc_bt':
+ worker.signals.finished.connect(self.dc_finish)
+ elif qt_sender == 'wb_bt':
+ worker.signals.finished.connect(self.wb_finish)
+
+ # 完成调焦、采集暗电流、采集白板后--------->>>>>采集影像和将影像写到硬盘上
+ def record_image_multiprocess(self):
+ # print('开始按钮点击事件正常!')
+ self.statu_tb.append('开始采集数据...')
+
+ # 当点击采集后,让这些按钮不能使用,当采集成功后再让这些按钮可以使用
+ self.record_bt.setEnabled(False)
+ self.focus_bt.setEnabled(False)
+ self.exposureTime_bt.setEnabled(False)
+ self.dc_bt.setEnabled(False)
+ self.wb_bt.setEnabled(False)
+ self.save_bt.setEnabled(False)
+
+ # 此共享变量是用来停止采集进程所用,所以每次开始前要把值设置为True
+ self.share_state.set(True)
+
+ # 共享变量(主线程和写进程之间共享),每次采集前都要清空上一次采集的内容(其实也不必要,因为采集的过程中也将内容全部都改变了)
+ self.rgb = np.ones(int(camera_operation.framenumber_input) * int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial)).astype(
+ np.float32)
+ self.share_r = multiprocessing.Array('f', self.rgb)
+ self.share_g = multiprocessing.Array('f', self.rgb)
+ self.share_b = multiprocessing.Array('f', self.rgb)
+
+ # 新建一个线程,在此线程中新建两个进程来采集数据
+ self.workThread.start()
+
+ def plot_img(self, r, g, b):
+ img_r = np.frombuffer(r.get_obj(), dtype=np.float32).reshape(int(camera_operation.framenumber_input), int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial))
+ img_g = np.frombuffer(g.get_obj(), dtype=np.float32).reshape(int(camera_operation.framenumber_input), int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial))
+ img_b = np.frombuffer(b.get_obj(), dtype=np.float32).reshape(int(camera_operation.framenumber_input), int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial))
+ # img = camera_operation.percentile_stretching(np.dstack((img_r, img_g, img_b)), 2, 98)
+ # img = np.dstack((img_r, img_g, img_b))
+ img = camera_operation.percentile_stretching(img_r, 2, 98)
+ print(img_r.max())
+ print(img.max())
+ try:
+ image_window_instance.myImageFigure.plot(img_r)
+ image_window_instance.myImageFigure.draw()
+ # image_window_instance.myImageFigure.plot(
+ # cls.percentile_stretching(np.dstack((rgb[2, :, :], rgb[1, :, :], rgb[0, :, :])), 2, 98))
+ # image_window_instance.myImageFigure.draw()
+ except:
+ traceback.print_exc()
+ finally:
+ traceback.print_exc()
+ print('画图出错')
+
+ # 用来停止采集数据
+ def stop_record(self):
+ # camera_operation.record = False
+ self.share_state.set(False)
+
+ # 用来停止调焦
+ def stop_focus(self):
+ camera_operation.focus = False
+
+ def record_finish(self, x):
+ print(x)
+
+ # 新建一个线程,用来显示图像
+ worker = Worker(self.plot_img, self.share_r, self.share_g, self.share_b)
+ self.threadpool.start(worker)
+
+ # 数据采集完成后,在界面上给出反馈
+ self.statu_tb.append('采集数据成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.record_bt.setEnabled(True)
+ self.focus_bt.setEnabled(True)
+ self.exposureTime_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.wb_bt.setEnabled(True)
+ self.save_bt.setEnabled(True)
+
+ def focus_finish(self):
+ self.statu_tb.append('调焦成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.record_bt.setEnabled(True)
+ self.focus_bt.setEnabled(True)
+ self.exposureTime_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.wb_bt.setEnabled(True)
+ self.save_bt.setEnabled(True)
+
+ def dc_finish(self):
+ self.statu_tb.append('采集暗电流成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.record_bt.setEnabled(True)
+ self.focus_bt.setEnabled(True)
+ self.exposureTime_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.wb_bt.setEnabled(True)
+ self.save_bt.setEnabled(True)
+
+ def wb_finish(self):
+ self.statu_tb.append('采集白板成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.record_bt.setEnabled(True)
+ self.focus_bt.setEnabled(True)
+ self.exposureTime_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.wb_bt.setEnabled(True)
+ self.save_bt.setEnabled(True)
+
+ # 设置曝光参数:exposure和gain
+ def exposure_finish(self):
+ self.statu_tb.append('自动曝光成功!')
+
+ # 当曝光完成后,让这些按钮恢复使用
+ self.record_bt.setEnabled(True)
+ self.focus_bt.setEnabled(True)
+ self.exposureTime_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.wb_bt.setEnabled(True)
+ self.save_bt.setEnabled(True)
+
+ # 将自动曝光返回值写入到界面中的QLineEdit
+ def changeTXT_QLineEdit(self, result):
+ # 将返回的曝光参数写入到界面中
+ self.exposureTime_le.setText(str(result[0]))
+ self.gain_le.setText(str(result[1]))
+ # 将返回的曝光参数写入到camera_operation类中
+ camera_operation.gain_input = self.gain_le.text()
+ camera_operation.exposureTime_input = self.exposureTime_le.text()
+ if result[2] == 1:
+ QMessageBox.information(self, '曝光提示', '光线不足,曝光时间已设置为最大!', QMessageBox.Yes)
+ camera_operation.autoexposure_feedback = 0
+
+ def save_image(self):
+ # 操作状态显示
+ self.statu_tb.append('保存影像...')
+
+ worker = Worker(camera_operation.savedata)
+ self.threadpool.start(worker)
+
+ # 操作状态显示
+ worker.signals.finished.connect(lambda: self.statu_tb.append('保存影像成功!'))
+
+ # (textChanged)将 自动曝光返回到QLineEdit中的值 写入camera_operation类对应的变量中
+ def onchange(self):
+ camera_operation.fn = self.filename_le.text()
+ camera_operation.fp = self.filepath_le.text()
+
+ # 在界面中改变帧数后,将新帧数写入camera_operation类中
+ camera_operation.framenumber_input = self.framenumber_le.text()
+
+ # 在界面中改变帧数后,需要将下面的参数更改一下,然后再传入record_image_multiprocess函数中写进程中去
+ self.rgb = np.ones(int(camera_operation.framenumber_input) * int(
+ (camera_operation.endColumn - camera_operation.startColumn) / camera_operation.bin_spatial)).astype(
+ np.float32)
+ self.share_r = multiprocessing.Array('f', self.rgb)
+ self.share_g = multiprocessing.Array('f', self.rgb)
+ self.share_b = multiprocessing.Array('f', self.rgb)
+
+ # 手动修改(textEdited)界面中的值后,写入camera_operation类对应的变量中
+ def onchange2(self):
+ camera_operation.gain_input = self.gain_le.text()
+ camera_operation.exposureTime_input = self.exposureTime_le.text()
+ camera_operation.framerate_input = self.framerate_le.text()
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', '/home')
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.filepath_le.setText(dirpath)
+ camera_operation.fp = dirpath
+
+# 光谱窗口 ########################################################################################################################################
+class spectral_window(QDialog, Ui_spectral_Window):
+ def __init__(self, parent=None):
+ super(spectral_window, self).__init__(parent)
+ self.setupUi(self)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化值
+ self.filename_le.setText('test')
+ self.filepath_le.setText(os.getcwd())
+
+ #手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filepath_bt.clicked.connect(self.directory_select)
+ self.filename_le.textEdited.connect(self.onchange)
+ self.filepath_le.textEdited.connect(self.onchange)
+
+
+ # 显示光谱和align
+ self.spectralFigure = MySpectralFigure_spectral()
+ self.spe_glo.addWidget(self.spectralFigure)
+ self.alignFigure = MyImageFigure()
+ self.align_glo.addWidget(self.alignFigure)
+
+ #操作光谱仪
+ # self.dc_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ self.wb_bt.clicked.connect(self.record_spectral_multithread) # 曝光 + 采集白板
+ self.align_bt.clicked.connect(self.record_spectral_multithread)
+ self.stop_align_bt.clicked.connect(self.stop_align) # 这个操作非常简单,耗时非常短,瞬间可回到event loop;所以不需要多线程
+ self.dc_bt.clicked.connect(self.record_spectral_multithread)
+ self.record_bt.clicked.connect(self.record_spectral_multithread)
+
+ def stop_align(self):
+ spectral_camera_operation.align = False
+
+ def record_spectral_multithread(self):
+ #
+ self.wb_bt.setEnabled(False)
+ self.align_bt.setEnabled(False)
+ self.dc_bt.setEnabled(False)
+ self.record_bt.setEnabled(False)
+
+ qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if qt_sender == 'wb_bt':
+ self.statu_tb.append('曝光/白板...')
+ elif qt_sender == 'align_bt':
+ self.statu_tb.append('align...')
+ elif qt_sender == 'dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ elif qt_sender == 'record_bt':
+ self.statu_tb.append('采集光谱...')
+
+ worker = Worker(spectral_camera_operation.start_AcquireData, qt_sender)
+ self.threadpool.start(worker)
+
+ # 操作状态显示
+ if qt_sender == 'wb_bt':
+ worker.signals.finished.connect(self.wb_finish)
+ elif qt_sender == 'align_bt':
+ worker.signals.finished.connect(self.align_finish)
+ elif qt_sender == 'dc_bt':
+ worker.signals.finished.connect(self.dc_finish)
+ elif qt_sender == 'record_bt':
+ worker.signals.finished.connect(self.record_finish)
+
+ def wb_finish(self):
+ self.statu_tb.append('曝光/白板成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.wb_bt.setEnabled(True)
+ self.align_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.record_bt.setEnabled(True)
+
+ def align_finish(self):
+ self.statu_tb.append('align successfully!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.wb_bt.setEnabled(True)
+ self.align_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.record_bt.setEnabled(True)
+
+ def dc_finish(self):
+ self.statu_tb.append('采集暗电流成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.wb_bt.setEnabled(True)
+ self.align_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.record_bt.setEnabled(True)
+
+ def record_finish(self):
+ self.statu_tb.append('采集光谱成功!')
+
+ # 当采集完成后,让这些按钮恢复使用
+ self.wb_bt.setEnabled(True)
+ self.align_bt.setEnabled(True)
+ self.dc_bt.setEnabled(True)
+ self.record_bt.setEnabled(True)
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ spectral_camera_operation.fn = self.filename_le.text()
+ spectral_camera_operation.fp = self.filepath_le.text()
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', '/home')
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.filepath_le.setText(dirpath)
+ spectral_camera_operation.fp = dirpath#
+
+# 画图类,用于:画出采集到的光谱;调焦(影响模式调焦)
+class MySpectralFigure_focus(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ #第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ #第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MySpectralFigure_focus, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, spectral):
+ self.axes.clear()
+ self.axes.plot(spectral)
+
+class MySpectralFigure_spectral(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MySpectralFigure_spectral, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ self.axes
+ #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, Wavelength, spectral):
+ self.axes.clear()
+ self.axes.plot(Wavelength, spectral)
+
+# 画图类,用于:画出采集到的图像;显示帧流(光谱模式对准光纤)
+class MyImageFigure(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MyImageFigure, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ # 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, frame):
+ self.axes.clear()
+ self.axes.imshow(frame)
+
+class WorkerSignals(QObject):
+ '''
+ Defines the signals available from a running worker thread.
+
+ Supported signals are:
+
+ finished
+ No data
+
+ error
+ `tuple` (exctype, value, traceback.format_exc() )
+
+ result
+ `object` data returned from processing, anything
+
+ progress
+ `int` indicating % progress
+
+ '''
+ finished = pyqtSignal()
+ error = pyqtSignal(tuple)
+ result = pyqtSignal(object)
+ progress = pyqtSignal(int)
+
+# 用于qt多线程:运行long-time task
+class Worker(QRunnable):
+ '''
+ Worker thread
+
+ Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
+
+ :param callback: The function callback to run on this worker thread. Supplied args and
+ kwargs will be passed through to the runner.
+ :type callback: function
+ :param args: Arguments to pass to the callback function
+ :param kwargs: Keywords to pass to the callback function
+
+ '''
+
+ def __init__(self, fn, *args, **kwargs):
+ super(Worker, self).__init__()
+
+ # Store constructor arguments (re-used for processing)
+ self.fn = fn
+ self.args = args
+ self.kwargs = kwargs
+ self.signals = WorkerSignals()
+
+ # Add the callback to our kwargs
+ # self.kwargs['progress_callback'] = self.signals.progress
+
+ @pyqtSlot()
+ def run(self):
+ '''
+ Initialise the runner function with passed args, kwargs.
+ '''
+
+ # Retrieve args/kwargs here; and fire processing using them
+
+ try:
+ result = self.fn(*self.args, **self.kwargs)
+ except:
+ traceback.print_exc()
+ exctype, value = sys.exc_info()[:2]
+ self.signals.error.emit((exctype, value, traceback.format_exc()))
+ else:
+ self.signals.result.emit(result) # Return the result of the processing
+ finally:
+ self.signals.finished.emit() # Done
+
+
+class WorkThread(QThread):
+ '''
+ 这是工作线程,界面点击“开始采集”按钮后,新建这个线程,避免界面卡死;然后在此线程中新建两个进程(分别负责采集数据和存储数据)
+ '''
+ def __init__(self):
+ super().__init__()
+
+
+ # 多进程代码思路来源:https://stackoverflow.com/questions/14410416/how-to-use-multicore-python-with-pyqt4-process
+ # https://stackoverflow.com/questions/29310824/how-to-implement-multicore-processing-in-python-3-and-pyqt5
+ # (1)网页中的代码使用的是pool.apply_async,但是这样运行有错;
+ # (2)我自己使用Process就没有问题
+ sinOut = pyqtSignal(str) # 自定义信号,执行run()函数时,从相关线程发射此信号
+ def run(self):
+
+ # 共享变量必须和Process类实例都在run函数内,共享变量放在在WorkThread类其他地方程序运行都会出错
+ q = Queue()
+ rgb = shm.full((3, int(100), int((1649 - 285) / 2)), 1, dtype=np.float32)
+
+ pr = Process(target=camera_operation.recordimg, args=(
+ camera_operation.startRow, camera_operation.endRow, camera_operation.startColumn,
+ camera_operation.endColumn, q, camera_operation.framenumber_input, camera_operation.framerate_input,
+ camera_operation.exposureTime_input, camera_operation.gain_input, camera_operation.image_dc,
+ camera_operation.image_wb, camera_operation.bin_spectral, camera_operation.bin_spatial,
+ image_window_instance.share_state))
+ # 如果注释掉写进程,会出现一个问题:第一次点击按钮可以正常采集,当采集完成后,第二次点击俺就就不能正常采集
+ pw = Process(target=camera_operation.writeimg, args=(
+ camera_operation.startRow, camera_operation.endRow, camera_operation.startColumn,
+ camera_operation.endColumn, q, camera_operation.bin_spectral, camera_operation.bin_spatial,
+ camera_operation.image_dc, camera_operation.image_wb, image_window_instance.share_r,
+ image_window_instance.share_g, image_window_instance.share_b))
+
+ # # 这样有问题,在界面中改变帧数输入后,点击开始;新的帧数并没有被新建的进程获取!!!!
+ # pr = Process(target=camera_operation.recordimg2, args=(q, image_window_instance.share_state))
+ # # 如果注释掉写进程,会出现一个问题:第一次点击按钮可以正常采集,当采集完成后,第二次点击俺就就不能正常采集
+ # pw = Process(target=camera_operation.writeimg2, args=(q, 1))
+
+ pr.start()
+ pw.start()
+ pr.join()
+ pw.terminate()
+ print('我才代表进程都正常结束!') # 两个进程中的代码都执行到了最后一句,代表进程正常结束了吧?但是为啥执行不到这句代码??????
+ self.sinOut.emit('采集完成!')
+
+
+# 影像模式类:相关的函数和变量
+class camera_operation(object):
+
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1649
+
+ # bin相关设置
+ bin_spectral = 1 # 光谱bin
+ bin_spatial = 1 # 空间bin
+ k = np.arange(endRow - startRow)[0::bin_spectral]
+ l = np.arange(endColumn - startColumn)[0::bin_spatial]
+
+ # 存储曝光时间和帧率
+ framerate_input = 30 # 随便给个初始值(初始值要和framerate_le控件初始值一致),从image_window获取的手动输入的帧率
+ exposureTime_input = 180 # 曝光时间单位为微秒,1s共有1000000微秒
+ gain_input = 0
+
+
+ # 开始采集数据
+ framenumber_input = 100 # 随便给个初始值(初始值要和framenumber_le控件初始值一致),从image_window获取的手动输入的帧数
+ image_dc = 1 # 随便给个初始值,此变量用于存储采集到的暗电流影像
+ image_wb = 1 # 随便给个初始值,此变量用于存储采集到的白板影像
+ focus = True # 用于停止调焦
+ record = True # 用于停止采集
+ # rgb = shm.full((3, int(framenumber_input), int((endColumn - startColumn) / bin_spatial)), 1, dtype=np.float32)
+
+
+
+ autoexposure_feedback = 0
+ @classmethod
+ def start_AcquireData(cls, qt_sender): # qt_sender是指qt窗口中事件的发生者
+ # create instance of Image to store image data and metadata
+ cam = open_camera2()
+ cam.set_framerate(int(cls.framerate_input))
+ cam.set_exposure(int(cls.exposureTime_input)) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(int(float(cls.gain_input)))
+ img = xiapi.Image()
+ # cam.get_buffer_policy()
+
+
+ if qt_sender == 'exposureTime_bt':
+ cam.set_framerate(int(cls.framerate_input))
+ cam.set_aeag_roi_offset_x(cls.startColumn)
+ cam.set_aeag_roi_offset_y(cls.startRow)
+ cam.set_aeag_roi_height(cls.endRow - cls.startRow)
+ cam.set_aeag_roi_width(cls.endColumn - cls.startColumn)
+ # cam.set_exp_priority(1) # Exposure priority (0.8 - exposure 80%, gain 20%).XI_PRM_EXP_PRIORITY
+ # cam.set_ae_max_limit(24000) # Maximum time (us) used for exposure in AEAG procedureXI_PRM_AE_MAX_LIMIT
+ # cam.set_ag_max_limit(12)
+ # cam.set_aeag_level(50) # Average intensity of output signal AEAG should achieve(in %)XI_PRM_AEAG_LEVEL
+ # 还有两个不知怎么用的参数:XI_PRM_GAIN_SELECTOR or "gain_selector"和XI_PRM_SHUTTER_TYPE or "shutter_type"
+ cam.enable_aeag() # 开启自动曝光
+ cam.start_acquisition()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ cam.disable_aeag() # 关闭自动曝光
+
+ # 判断是否光线不足,如果不足,提示用户
+ if cam.get_exposure() > int(1 / int(cls.framerate_input) * 10**6):
+ cam.set_exposure(int(1 / int(cls.framerate_input) * 10**6))
+ cls.autoexposure_feedback = 1
+
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 自动曝光返回值放在本函数(start_AcquireData)的最后
+
+ # 如果点击“调焦”按钮
+ if qt_sender == 'focus_bt':
+ cam.start_acquisition()
+ cam.set_framerate(10)
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not cls.focus:
+ cls.focus = True
+ while cls.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+ image_window_instance.myFocusFigure.plot(image_container[150, :])
+ image_window_instance.myFocusFigure.draw()
+
+ # 如果点击“白板”按钮,采集并保存白板影像到image_wb
+ if qt_sender == 'wb_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ cls.image_wb = image_container_bin
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'dc_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ cls.image_dc = image_container_bin
+
+ # stop data acquisition
+ print('Stopping acquisition...')
+
+
+ # 自动曝光所需的返回参数
+ cam.stop_acquisition()
+ exposure = cam.get_exposure()
+ gain = cam.get_gain()
+ cam.close_device()
+
+ # 只有自动曝光才用得上的代码
+ return exposure, gain, cls.autoexposure_feedback # 只有自动曝光会用返回值,其他时候都用不上返回值
+
+ @classmethod
+ def recordimg(cls, startRow, endRow, startColumn, endColumn, q, framenumber_input, framerate_input,
+ exposureTime_input, gain_input, image_dc, image_wb, bin_spectral, bin_spatial, share_state):
+ print('已经启动读影像进程!')
+
+ cam = open_camera2()
+ cam.set_framerate(int(framerate_input))
+ cam.set_exposure(int(exposureTime_input)) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(int(float(gain_input))) # int('0.0')会报错,int(float('0.0'))不会报错
+ img = xiapi.Image()
+
+ print('相机的帧率设置为:%s' % str(cam.get_framerate()))
+ print('相机的曝光设置为:%s' % str(cam.get_exposure()))
+ print('相机的Gain设置为:%s' % str(cam.get_gain()))
+
+ cam.start_acquisition()
+ startTime = datetime.datetime.now()
+ recordframeCount = 1
+ while share_state.value:
+ # print("record: %s" % recordframeCount)
+ cam.get_image(img)
+ # image_raw_numpy.dtype -> dtype(' dtype(' maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+ else: # 对于彩色照片,需要先单独对每个波段拉伸
+ img_new = np.empty(img.shape)
+ for i in range(img.shape[2]):
+ low = np.percentile(img[:, :, i], lowPercentile)
+ up = np.percentile(img[:, :, i], highPercentile)
+
+ img_new[:, :, i] = minout + ((img[:, :, i] - low) / (up - low)) * (maxout - minout)
+ img_new[:, :, i][img_new[:, :, i] < minout] = minout
+ img_new[:, :, i][img_new[:, :, i] > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+
+ @classmethod
+ def close_camera(cls, cam):
+ cam.stop_acquisition()
+ cam.close_device()
+
+
+# 光谱模式类:相关的函数和变量
+class spectral_camera_operation(object):
+
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1650
+
+ # 存储曝光时间和帧率
+ framerate_input = 15 # 随便给个初始值(初始值要和framerate_le控件初始值一致),从image_window获取的手动输入的帧率
+ exposureTime_input = 180 # 曝光时间单位为微秒,1s共有1000000微秒
+ gain_input = 0
+
+ # 开始采集数据
+ fp = os.getcwd() # 随便给个初始值(初始值要和filepath_le控件初始值一致),从spectral_window获取的手动输入的帧率
+ fn = 'test' # 随便给个初始值(初始值要和filename_le控件初始值一致),从spectral_window获取的手动输入的帧率
+
+ framenumber = 10 # 每条光谱为多少帧平均得到
+ spectral_container = np.empty((endRow - startRow, framenumber, endColumn - startColumn)).astype(np.float)
+ # spectral_container = np.empty((300, framenumber, 3)).astype(np.float64)
+
+ align = True # 用于对准光纤
+ image_dc = np.empty((endRow - startRow, endColumn - startColumn)) # 此变量用于存储采集到的暗电流,一帧
+ spectralNumber_wb = 1 # 每次采集的白板的光谱数
+ spectral_wb = np.empty((endRow - startRow, endColumn - startColumn)) # 此变量用于存储采集到的白板,一帧
+ spectral_wb_tmp = np.empty((endRow - startRow, framenumber, endColumn - startColumn)).astype(
+ np.float64) # 随便给个初始值,此变量用于存储采集到的白板影像,后面白板影像去除了暗电流后值赋给spectral_wb
+ spectralNumber = 10 # 每次采集目标物的光谱数
+ spectral = np.empty((endRow - startRow, spectralNumber)).astype(np.float) # 此ndarray用于存储采集到的目标物光谱,每一列为一个光谱
+
+ @classmethod
+ def start_AcquireData(cls, qt_sender):
+
+ cam = open_camera2()
+ cam.set_framerate(int(cls.framerate_input))
+ cam.set_exposure(int(cls.exposureTime_input)) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(int(float(cls.gain_input)))
+ print('点击函数最开始')
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+ img = xiapi.Image()
+
+ print('Starting data acquisition...')
+ starttime = datetime.datetime.now()
+
+
+ # 如果点击“曝光/白板”按钮:(1)先自动曝光;(2)然后在采集白板
+ if qt_sender == 'wb_bt':
+
+ # 自动曝光
+ cam.set_aeag_roi_offset_x(cls.startColumn)
+ cam.set_aeag_roi_offset_y(cls.startRow)
+ cam.set_aeag_roi_height(cls.endRow - cls.startRow)
+ cam.set_aeag_roi_width(cls.endColumn - cls.startColumn)
+ # cam.set_exp_priority(1) # Exposure priority (0.8 - exposure 80%, gain 20%).XI_PRM_EXP_PRIORITY
+ # cam.set_ae_max_limit(24000) # Maximum time (us) used for exposure in AEAG procedureXI_PRM_AE_MAX_LIMIT
+ # cam.set_ag_max_limit(12)
+ # cam.set_aeag_level(50) # Average intensity of output signal AEAG should achieve(in %)XI_PRM_AEAG_LEVEL
+ # 还有两个不知怎么用的参数:XI_PRM_GAIN_SELECTOR or "gain_selector"和XI_PRM_SHUTTER_TYPE or "shutter_type"
+ cam.enable_aeag()
+ cam.start_acquisition()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ cam.disable_aeag()
+
+ # 将自动曝光获得的exposure和gain写入到相机
+ cam.set_exposure(cam.get_exposure())
+ cam.set_gain(cam.get_gain())
+ # 将自动曝光获得的exposure和gain写入到本类中(spectral_camera_operation)
+ cls.exposureTime_input = cam.get_exposure()
+ cls.gain_input = cam.get_gain()
+
+ spectral_window_instance.statu_tb.append('Exposure: ' + str(cam.get_exposure()) + ' us')
+ spectral_window_instance.statu_tb.append('Framerate: ' + str(cam.get_framerate()) + ' FPS')
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 开始采集白板数据,去除白板暗电流的操作放在采集暗电流时进行
+ cam.start_acquisition()
+ for j in range(cls.spectralNumber_wb):
+ for i in range(cls.framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow,
+ cls.startColumn:cls.endColumn]
+
+ # 去除白板暗电流的操作放在采集暗电流时进行
+ # cls.spectral_container没经过运算,传给cls.spectral_wb_tmp的是cls.spectral_container的内存地址
+ cls.spectral_wb_tmp = cls.spectral_container
+
+ # 存储原始白板影像
+ filename = cls.fp + '\\' + 'baiban'
+ with open(filename, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_wb_tmp[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # 如果点击“align”按钮
+ if qt_sender == 'align_bt':
+
+ if not cls.align:
+ cls.align = True
+
+ cam.start_acquisition()
+ while cls.align:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ spectral_window_instance.alignFigure.plot(image_raw_numpy)
+ spectral_window_instance.alignFigure.draw()
+
+ # 如果点击“暗电流”按钮
+ if qt_sender == 'dc_bt':
+ print('点暗电流')
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+ # 为cls.spectral_container新建立一个内存地址,以免改变cls.spectral_wb_tmp(传址)的值
+ cls.spectral_container = np.empty(
+ (cls.endRow - cls.startRow, cls.framenumber, cls.endColumn - cls.startColumn)).astype(np.float64)
+ cam.start_acquisition()
+ for i in range(cls.framenumber):#此循环为啥会改变649行的赋值的结果呢?怎么会执行那里的代码
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+
+ # 存储暗电流影像
+ filename1 = cls.fp + '\\' + 'dark'
+ with open(filename1, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename1, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # cls.spectral_container经过运算,传给cls.image_dc的不是cls.spectral_container的内存地址,是新运算结果的内存地址;相当于传值
+ cls.image_dc = cls.spectral_container.mean(axis=1) # 因为平均,cls.image_dc的数据类型为:dtype('float64')
+
+
+
+ # 去除白板暗电流
+ for i in range(cls.framenumber):
+ cls.spectral_wb_tmp[:, i, :] = cls.spectral_wb_tmp[:, i, :] - cls.image_dc
+
+
+ # 存储扣除暗电流的白板影像
+ filename2 = cls.fp + '\\' + 'baiban_rmdark'
+ with open(filename2, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_wb_tmp[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename2, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ cls.spectral_wb = cls.spectral_wb_tmp.mean(axis=1) # 因为平均,cls.spectral_wb的数据类型为:dtype('float64')
+
+ # 如果点击“采集”按钮,去除暗电流,转化成反射率
+ if qt_sender == 'record_bt':
+ print('点暗采集')
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+ cam.start_acquisition()
+ for j in range(cls.spectralNumber):
+ for i in range(cls.framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ # 存储扣除暗电流前的目标物影像
+ if j == 1:
+ filename1 = cls.fp + '\\' + cls.fn
+ with open(filename1, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename1, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ for i in range(cls.framenumber): # (1)去除暗电流;(2)转反射率
+ cls.spectral_container[:, i, :] = (cls.spectral_container[:, i, :] - cls.image_dc) / cls.spectral_wb
+
+ # 存储目标物反射率影像
+ if j == 1:
+ filename2 = cls.fp + '\\' + cls.fn + '_ref'
+ with open(filename2, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ camera_operation.write_hdr(filename2, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # spectral_tmp = cls.spectral_container.sum(axis=1).sum(axis=1)
+ spectral_tmp = cls.spectral_container.mean(axis=1).mean(axis=1)
+
+ cls.spectral[:, j] = spectral_tmp
+
+
+ # 画出光谱
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+ wavelength = np.empty(cls.endRow - cls.startRow)
+ for i in range(cls.startRow, cls.endRow):
+ wavelength[i - cls.startRow] = calculate_wavelength(i)
+ spectral_window_instance.spectralFigure.plot(wavelength, spectral_tmp)
+ spectral_window_instance.spectralFigure.draw()
+
+ # 计算波长
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+ wavelength = np.empty(cls.endRow - cls.startRow)
+ for i in range(cls.startRow, cls.endRow):
+ wavelength[i - cls.startRow] = calculate_wavelength(i)
+ # 保存光谱为txt文件
+ cls.spectral = np.insert(cls.spectral, 0, wavelength, axis=1)
+ for i in range(cls.spectralNumber):
+ np.savetxt(cls.fp + '\\' + cls.fn + str(i) + '.txt', cls.spectral[:, [0, i + 1]], fmt='%f')
+
+ endtime = datetime.datetime.now()
+ print('光谱采集用时:%d' % (endtime - starttime).seconds)
+
+ # stop data acquisition
+ print('Stopping acquisition...')
+ cls.close_camera(cam)
+
+ @classmethod
+ def close_camera(cls, cam):
+ cam.stop_acquisition()
+ cam.close_device()
+
+
+def open_camera2():
+ cam = xiapi.Camera()
+ cam.open_device()
+ cam.set_proc_num_threads(8)
+ cam.set_acq_timing_mode('XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ cam.set_imgdataformat('XI_RAW16')
+ return cam
+
+# 打开相机
+def open_camera():
+ # create instance for first connected camera
+ cam = xiapi.Camera()
+
+ # start communication to open specific device, use: cam.open_device_by_SN('41305651')
+ print('Opening first camera...')
+ cam.open_device()
+
+ # 打开相机后,显示相机信息
+ print('SN: %s' % str(cam.get_device_sn(), encoding="utf-8"))
+ print('Device name: %s' % str(cam.get_device_name(), encoding="utf-8"))
+ print('Device name: %s' % str(cam.get_device_type(), encoding="utf-8"))
+ print('Instance path: %s' % str(cam.get_device_inst_path(),
+ encoding="utf-8")) # Returns device instance path in operating system.
+ print('Location path: %s' % str(cam.get_device_loc_path(), encoding="utf-8"))
+
+ print('Debug level: %s' % cam.get_debug_level())
+ print('Default number of threads per image processor: %d' % cam.get_proc_num_threads())
+ cam.set_proc_num_threads(8)
+ print('Current number of threads per image processor: %d' % cam.get_proc_num_threads())
+ print('Is horizontal flip enabled?, %s' % str(cam.is_horizontal_flip()))
+ print()
+
+ # This mode is supported by selected camera families: CB, MC, MT, MX
+ cam.set_acq_timing_mode('XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ mode_used = cam.get_acq_timing_mode()
+ if mode_used == 'XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT':
+ print('Mode is XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ else:
+ print('Mode is not XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ sys.exit()
+
+ return cam
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ #实例化3个窗口
+ enter_window_instance = enter_window()
+ image_window_instance = image_window()
+ image_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ spectral_window_instance = spectral_window()
+ spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+
+ enter_window_instance.c.openinfo.emit()
+
+
+ #从主窗口弹出影像窗口和光谱窗口
+ enter_window_instance.image_mode_bt.clicked.connect(image_window_instance.show)
+ enter_window_instance.spectral_mode_bt.clicked.connect(spectral_window_instance.show)
+
+
+ enter_window_instance.show()
+ sys.exit(app.exec_())
diff --git a/record_system_v23/arcus_control_ui.py b/record_system_v23/arcus_control_ui.py
new file mode 100644
index 0000000..640777f
--- /dev/null
+++ b/record_system_v23/arcus_control_ui.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'arcus_control_ui.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_arcus_ui(object):
+ def setupUi(self, arcus_ui):
+ arcus_ui.setObjectName("arcus_ui")
+ arcus_ui.resize(354, 171)
+ self.centralwidget = QtWidgets.QWidget(arcus_ui)
+ self.centralwidget.setObjectName("centralwidget")
+ self.left_btn = QtWidgets.QPushButton(self.centralwidget)
+ self.left_btn.setGeometry(QtCore.QRect(100, 90, 61, 21))
+ self.left_btn.setObjectName("left_btn")
+ self.right_btn = QtWidgets.QPushButton(self.centralwidget)
+ self.right_btn.setGeometry(QtCore.QRect(170, 90, 61, 23))
+ self.right_btn.setObjectName("right_btn")
+ self.speed_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
+ self.speed_lineEdit.setGeometry(QtCore.QRect(101, 10, 131, 20))
+ self.speed_lineEdit.setObjectName("speed_lineEdit")
+ self.speed_ScrollBar = QtWidgets.QScrollBar(self.centralwidget)
+ self.speed_ScrollBar.setGeometry(QtCore.QRect(100, 40, 131, 20))
+ self.speed_ScrollBar.setOrientation(QtCore.Qt.Horizontal)
+ self.speed_ScrollBar.setObjectName("speed_ScrollBar")
+ arcus_ui.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(arcus_ui)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 354, 23))
+ self.menubar.setObjectName("menubar")
+ arcus_ui.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(arcus_ui)
+ self.statusbar.setObjectName("statusbar")
+ arcus_ui.setStatusBar(self.statusbar)
+
+ self.retranslateUi(arcus_ui)
+ QtCore.QMetaObject.connectSlotsByName(arcus_ui)
+
+ def retranslateUi(self, arcus_ui):
+ _translate = QtCore.QCoreApplication.translate
+ arcus_ui.setWindowTitle(_translate("arcus_ui", "MainWindow"))
+ self.left_btn.setText(_translate("arcus_ui", "左"))
+ self.right_btn.setText(_translate("arcus_ui", "右"))
diff --git a/record_system_v23/arcus_control_ui.ui b/record_system_v23/arcus_control_ui.ui
new file mode 100644
index 0000000..b494281
--- /dev/null
+++ b/record_system_v23/arcus_control_ui.ui
@@ -0,0 +1,81 @@
+
+
+ arcus_ui
+
+
+
+ 0
+ 0
+ 354
+ 171
+
+
+
+ MainWindow
+
+
+
+
+
+ 100
+ 90
+ 61
+ 21
+
+
+
+ 左
+
+
+
+
+
+ 170
+ 90
+ 61
+ 23
+
+
+
+ 右
+
+
+
+
+
+ 101
+ 10
+ 131
+ 20
+
+
+
+
+
+
+ 100
+ 40
+ 131
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v23/enter_window.py b/record_system_v23/enter_window.py
new file mode 100644
index 0000000..9f5f1cd
--- /dev/null
+++ b/record_system_v23/enter_window.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'enter_window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_enter_Window(object):
+ def setupUi(self, enter_Window):
+ enter_Window.setObjectName("enter_Window")
+ enter_Window.resize(651, 474)
+ self.centralwidget = QtWidgets.QWidget(enter_Window)
+ self.centralwidget.setObjectName("centralwidget")
+ self.image_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.image_mode_bt.setGeometry(QtCore.QRect(200, 180, 111, 51))
+ self.image_mode_bt.setObjectName("image_mode_bt")
+ self.spectral_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.spectral_mode_bt.setGeometry(QtCore.QRect(360, 180, 111, 51))
+ self.spectral_mode_bt.setObjectName("spectral_mode_bt")
+ self.camstatus_tb = QtWidgets.QTextBrowser(self.centralwidget)
+ self.camstatus_tb.setGeometry(QtCore.QRect(200, 240, 271, 81))
+ self.camstatus_tb.setObjectName("camstatus_tb")
+ enter_Window.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(enter_Window)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 651, 26))
+ self.menubar.setObjectName("menubar")
+ enter_Window.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(enter_Window)
+ self.statusbar.setObjectName("statusbar")
+ enter_Window.setStatusBar(self.statusbar)
+ self.actionwew_e = QtWidgets.QAction(enter_Window)
+ self.actionwew_e.setObjectName("actionwew_e")
+
+ self.retranslateUi(enter_Window)
+ QtCore.QMetaObject.connectSlotsByName(enter_Window)
+
+ def retranslateUi(self, enter_Window):
+ _translate = QtCore.QCoreApplication.translate
+ enter_Window.setWindowTitle(_translate("enter_Window", "主窗口"))
+ self.image_mode_bt.setText(_translate("enter_Window", "影像模式"))
+ self.spectral_mode_bt.setText(_translate("enter_Window", "光谱模式"))
+ self.actionwew_e.setText(_translate("enter_Window", "wew e"))
diff --git a/record_system_v23/enter_window.ui b/record_system_v23/enter_window.ui
new file mode 100644
index 0000000..4c39418
--- /dev/null
+++ b/record_system_v23/enter_window.ui
@@ -0,0 +1,73 @@
+
+
+ enter_Window
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+
+
+ 200
+ 180
+ 111
+ 51
+
+
+
+ 影像模式
+
+
+
+
+
+ 360
+ 180
+ 111
+ 51
+
+
+
+ 光谱模式
+
+
+
+
+
+ 200
+ 240
+ 271
+ 81
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v23/image_Window.py b/record_system_v23/image_Window.py
new file mode 100644
index 0000000..53dc349
--- /dev/null
+++ b/record_system_v23/image_Window.py
@@ -0,0 +1,231 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window(object):
+ def setupUi(self, image_Window):
+ image_Window.setObjectName("image_Window")
+ image_Window.setEnabled(True)
+ image_Window.resize(1181, 683)
+ image_Window.setMouseTracking(False)
+ image_Window.setAutoFillBackground(False)
+ image_Window.setSizeGripEnabled(False)
+ image_Window.setModal(False)
+ self.verticalLayout_7 = QtWidgets.QVBoxLayout(image_Window)
+ self.verticalLayout_7.setObjectName("verticalLayout_7")
+ self.groupBox_5 = QtWidgets.QGroupBox(image_Window)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
+ self.groupBox_5.setSizePolicy(sizePolicy)
+ self.groupBox_5.setObjectName("groupBox_5")
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.groupBox_5)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem)
+ self.splitter_3 = QtWidgets.QSplitter(self.groupBox_5)
+ self.splitter_3.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter_3.setObjectName("splitter_3")
+ self.layoutWidget = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(self.layoutWidget)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.label_4 = QtWidgets.QLabel(self.layoutWidget)
+ self.label_4.setObjectName("label_4")
+ self.verticalLayout.addWidget(self.label_4)
+ self.layoutWidget1 = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget1.setObjectName("layoutWidget1")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget1)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.filepath_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filepath_le.setObjectName("filepath_le")
+ self.verticalLayout_2.addWidget(self.filepath_le)
+ self.filename_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filename_le.setObjectName("filename_le")
+ self.verticalLayout_2.addWidget(self.filename_le)
+ self.layoutWidget2 = QtWidgets.QWidget(self.splitter_3)
+ self.layoutWidget2.setObjectName("layoutWidget2")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.layoutWidget2)
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.filepath_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.verticalLayout_3.addWidget(self.filepath_bt)
+ self.save_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout_3.addWidget(self.save_bt)
+ self.horizontalLayout_4.addWidget(self.splitter_3)
+ spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem1)
+ self.verticalLayout_7.addWidget(self.groupBox_5)
+ self.splitter = QtWidgets.QSplitter(image_Window)
+ self.splitter.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter.setObjectName("splitter")
+ self.groupBox_3 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth())
+ self.groupBox_3.setSizePolicy(sizePolicy)
+ self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0))
+ self.groupBox_3.setMaximumSize(QtCore.QSize(2000, 16777215))
+ self.groupBox_3.setObjectName("groupBox_3")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_3)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.groupBox = QtWidgets.QGroupBox(self.groupBox_3)
+ self.groupBox.setObjectName("groupBox")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.horizontalLayout.addLayout(self.image_glo)
+ self.verticalLayout_4.addWidget(self.groupBox)
+ self.statu_tb = QtWidgets.QTextBrowser(self.groupBox_3)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.statu_tb.sizePolicy().hasHeightForWidth())
+ self.statu_tb.setSizePolicy(sizePolicy)
+ self.statu_tb.setMaximumSize(QtCore.QSize(8777215, 100))
+ self.statu_tb.setReadOnly(True)
+ self.statu_tb.setObjectName("statu_tb")
+ self.verticalLayout_4.addWidget(self.statu_tb)
+ self.groupBox_4 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_4.sizePolicy().hasHeightForWidth())
+ self.groupBox_4.setSizePolicy(sizePolicy)
+ self.groupBox_4.setObjectName("groupBox_4")
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_4)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox_4)
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_2)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.horizontalLayout_2.addLayout(self.focus_glo)
+ self.verticalLayout_5.addWidget(self.groupBox_2)
+ self.groupBox_6 = QtWidgets.QGroupBox(self.groupBox_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_6.sizePolicy().hasHeightForWidth())
+ self.groupBox_6.setSizePolicy(sizePolicy)
+ self.groupBox_6.setObjectName("groupBox_6")
+ self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.groupBox_6)
+ self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+ self.groupBox_7 = QtWidgets.QGroupBox(self.groupBox_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
+ self.groupBox_7.setSizePolicy(sizePolicy)
+ self.groupBox_7.setMaximumSize(QtCore.QSize(500, 500))
+ self.groupBox_7.setObjectName("groupBox_7")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.verticalLayout_6 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_6.setObjectName("verticalLayout_6")
+ self.label_3 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout_6.addWidget(self.label_3)
+ self.focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.focus_bt.setObjectName("focus_bt")
+ self.verticalLayout_6.addWidget(self.focus_bt)
+ self.exposureTime_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.exposureTime_bt.setObjectName("exposureTime_bt")
+ self.verticalLayout_6.addWidget(self.exposureTime_bt)
+ self.label_5 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_5.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_5.setObjectName("label_5")
+ self.verticalLayout_6.addWidget(self.label_5)
+ self.wb_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.wb_bt.setObjectName("wb_bt")
+ self.verticalLayout_6.addWidget(self.wb_bt)
+ self.label_2 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout_6.addWidget(self.label_2)
+ self.record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.record_bt.setObjectName("record_bt")
+ self.verticalLayout_6.addWidget(self.record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_6)
+ self.verticalLayout_8 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_8.setObjectName("verticalLayout_8")
+ self.framerate_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.verticalLayout_8.addWidget(self.framerate_le)
+ self.stop_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.stop_focus_bt.setObjectName("stop_focus_bt")
+ self.verticalLayout_8.addWidget(self.stop_focus_bt)
+ self.exposureTime_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.exposureTime_le.setObjectName("exposureTime_le")
+ self.verticalLayout_8.addWidget(self.exposureTime_le)
+ self.gain_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.gain_le.setObjectName("gain_le")
+ self.verticalLayout_8.addWidget(self.gain_le)
+ self.dc_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.dc_bt.setObjectName("dc_bt")
+ self.verticalLayout_8.addWidget(self.dc_bt)
+ self.framenumber_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.verticalLayout_8.addWidget(self.framenumber_le)
+ self.motor_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.motor_bt.setObjectName("motor_bt")
+ self.verticalLayout_8.addWidget(self.motor_bt)
+ self.stop_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.stop_record_bt.setObjectName("stop_record_bt")
+ self.verticalLayout_8.addWidget(self.stop_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_8)
+ self.horizontalLayout_5.addWidget(self.groupBox_7)
+ spacerItem2 = QtWidgets.QSpacerItem(261, 17, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_5.addItem(spacerItem2)
+ self.verticalLayout_5.addWidget(self.groupBox_6)
+ self.verticalLayout_7.addWidget(self.splitter)
+
+ self.retranslateUi(image_Window)
+ QtCore.QMetaObject.connectSlotsByName(image_Window)
+
+ def retranslateUi(self, image_Window):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window.setWindowTitle(_translate("image_Window", "影像窗口"))
+ self.groupBox_5.setTitle(_translate("image_Window", "GroupBox"))
+ self.label.setText(_translate("image_Window", "保存路径"))
+ self.label_4.setText(_translate("image_Window", "文件名"))
+ self.filepath_bt.setText(_translate("image_Window", "浏览"))
+ self.save_bt.setText(_translate("image_Window", "保存"))
+ self.groupBox_3.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox.setTitle(_translate("image_Window", "图像"))
+ self.groupBox_4.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_2.setTitle(_translate("image_Window", "光谱"))
+ self.groupBox_6.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_7.setTitle(_translate("image_Window", "GroupBox"))
+ self.label_3.setText(_translate("image_Window", "帧率"))
+ self.focus_bt.setText(_translate("image_Window", "调焦"))
+ self.exposureTime_bt.setText(_translate("image_Window", "曝光"))
+ self.label_5.setText(_translate("image_Window", "gain"))
+ self.wb_bt.setText(_translate("image_Window", "白板"))
+ self.label_2.setText(_translate("image_Window", "帧数"))
+ self.record_bt.setText(_translate("image_Window", "采集"))
+ self.stop_focus_bt.setText(_translate("image_Window", "停止调焦"))
+ self.dc_bt.setText(_translate("image_Window", "暗电流"))
+ self.motor_bt.setText(_translate("image_Window", "马达"))
+ self.stop_record_bt.setText(_translate("image_Window", "停止采集"))
diff --git a/record_system_v23/image_Window.ui b/record_system_v23/image_Window.ui
new file mode 100644
index 0000000..c2133b3
--- /dev/null
+++ b/record_system_v23/image_Window.ui
@@ -0,0 +1,377 @@
+
+
+ image_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 1181
+ 683
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
-
+
+
+ 保存路径
+
+
+
+ -
+
+
+ 文件名
+
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ 浏览
+
+
+
+ -
+
+
+ 保存
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 2000
+ 16777215
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 图像
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 8777215
+ 100
+
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+ -
+
+
+ 光谱
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 500
+ 500
+
+
+
+ GroupBox
+
+
+
-
+
+
-
+
+
+ 帧率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 调焦
+
+
+
+ -
+
+
+ 曝光
+
+
+
+ -
+
+
+ gain
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 白板
+
+
+
+ -
+
+
+ 帧数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ -
+
+
+ 停止调焦
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ -
+
+
+ 马达
+
+
+
+ -
+
+
+ 停止采集
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 261
+ 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v23/spectral_Window.py b/record_system_v23/spectral_Window.py
new file mode 100644
index 0000000..749f060
--- /dev/null
+++ b/record_system_v23/spectral_Window.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window(object):
+ def setupUi(self, spectral_Window):
+ spectral_Window.setObjectName("spectral_Window")
+ spectral_Window.resize(792, 523)
+ self.label = QtWidgets.QLabel(spectral_Window)
+ self.label.setGeometry(QtCore.QRect(54, 10, 51, 20))
+ self.label.setObjectName("label")
+ self.filepath_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filepath_le.setGeometry(QtCore.QRect(131, 10, 261, 21))
+ self.filepath_le.setObjectName("filepath_le")
+ self.label_2 = QtWidgets.QLabel(spectral_Window)
+ self.label_2.setGeometry(QtCore.QRect(54, 40, 41, 20))
+ self.label_2.setObjectName("label_2")
+ self.filename_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filename_le.setGeometry(QtCore.QRect(131, 40, 261, 21))
+ self.filename_le.setObjectName("filename_le")
+ self.filepath_bt = QtWidgets.QPushButton(spectral_Window)
+ self.filepath_bt.setGeometry(QtCore.QRect(401, 10, 71, 21))
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.statu_tb = QtWidgets.QTextBrowser(spectral_Window)
+ self.statu_tb.setGeometry(QtCore.QRect(611, 210, 161, 301))
+ self.statu_tb.setObjectName("statu_tb")
+ self.tabWidget = QtWidgets.QTabWidget(spectral_Window)
+ self.tabWidget.setGeometry(QtCore.QRect(10, 70, 591, 441))
+ self.tabWidget.setObjectName("tabWidget")
+ self.tab = QtWidgets.QWidget()
+ self.tab.setObjectName("tab")
+ self.gridLayoutWidget = QtWidgets.QWidget(self.tab)
+ self.gridLayoutWidget.setGeometry(QtCore.QRect(0, 0, 581, 411))
+ self.gridLayoutWidget.setObjectName("gridLayoutWidget")
+ self.spe_glo = QtWidgets.QGridLayout(self.gridLayoutWidget)
+ self.spe_glo.setContentsMargins(0, 0, 0, 0)
+ self.spe_glo.setObjectName("spe_glo")
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_2 = QtWidgets.QWidget()
+ self.tab_2.setObjectName("tab_2")
+ self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab_2)
+ self.gridLayoutWidget_2.setGeometry(QtCore.QRect(-1, -1, 581, 411))
+ self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
+ self.align_glo = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
+ self.align_glo.setContentsMargins(0, 0, 0, 0)
+ self.align_glo.setObjectName("align_glo")
+ self.tabWidget.addTab(self.tab_2, "")
+ self.layoutWidget = QtWidgets.QWidget(spectral_Window)
+ self.layoutWidget.setGeometry(QtCore.QRect(610, 90, 195, 135))
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.align_bt.setObjectName("align_bt")
+ self.gridLayout.addWidget(self.align_bt, 0, 0, 1, 1)
+ self.stop_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.stop_align_bt.setObjectName("stop_align_bt")
+ self.gridLayout.addWidget(self.stop_align_bt, 0, 1, 1, 1)
+ self.wb_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.wb_bt.setObjectName("wb_bt")
+ self.gridLayout.addWidget(self.wb_bt, 1, 0, 1, 2)
+ self.dc_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.dc_bt.setObjectName("dc_bt")
+ self.gridLayout.addWidget(self.dc_bt, 2, 0, 1, 2)
+ self.record_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.record_bt.setObjectName("record_bt")
+ self.gridLayout.addWidget(self.record_bt, 3, 0, 1, 2)
+
+ self.retranslateUi(spectral_Window)
+ self.tabWidget.setCurrentIndex(0)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window)
+
+ def retranslateUi(self, spectral_Window):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window.setWindowTitle(_translate("spectral_Window", "光谱窗口"))
+ self.label.setText(_translate("spectral_Window", "保存路径"))
+ self.label_2.setText(_translate("spectral_Window", "文件名"))
+ self.filepath_bt.setText(_translate("spectral_Window", "浏览"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("spectral_Window", "spe"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("spectral_Window", "align"))
+ self.align_bt.setText(_translate("spectral_Window", "align"))
+ self.stop_align_bt.setText(_translate("spectral_Window", "stop align"))
+ self.wb_bt.setText(_translate("spectral_Window", "曝光/白板"))
+ self.dc_bt.setText(_translate("spectral_Window", "暗电流"))
+ self.record_bt.setText(_translate("spectral_Window", "采集"))
diff --git a/record_system_v23/spectral_Window.ui b/record_system_v23/spectral_Window.ui
new file mode 100644
index 0000000..f2641b7
--- /dev/null
+++ b/record_system_v23/spectral_Window.ui
@@ -0,0 +1,180 @@
+
+
+ spectral_Window
+
+
+
+ 0
+ 0
+ 792
+ 523
+
+
+
+ 光谱窗口
+
+
+
+
+ 54
+ 10
+ 51
+ 20
+
+
+
+ 保存路径
+
+
+
+
+
+ 131
+ 10
+ 261
+ 21
+
+
+
+
+
+
+ 54
+ 40
+ 41
+ 20
+
+
+
+ 文件名
+
+
+
+
+
+ 131
+ 40
+ 261
+ 21
+
+
+
+
+
+
+ 401
+ 10
+ 71
+ 21
+
+
+
+ 浏览
+
+
+
+
+
+ 611
+ 210
+ 161
+ 301
+
+
+
+
+
+
+ 10
+ 70
+ 591
+ 441
+
+
+
+ 0
+
+
+
+ spe
+
+
+
+
+ 0
+ 0
+ 581
+ 411
+
+
+
+
+
+
+
+ align
+
+
+
+
+ -1
+ -1
+ 581
+ 411
+
+
+
+
+
+
+
+
+
+ 610
+ 90
+ 195
+ 135
+
+
+
+ -
+
+
+ align
+
+
+
+ -
+
+
+ stop align
+
+
+
+ -
+
+
+ 曝光/白板
+
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v24/2record_system_v24.py b/record_system_v24/2record_system_v24.py
new file mode 100644
index 0000000..17ce4d0
--- /dev/null
+++ b/record_system_v24/2record_system_v24.py
@@ -0,0 +1,1828 @@
+# -*- coding:utf-8 -*-
+
+'''
+在2record system_v2.2的基础上更新:
+1、改变了命名以符合PEP 8风格
+2、增加了配置文件
+3、加入温湿度传感器:串口,并将温湿度写入文件
+4、加入异常处理机制(try/except/else/finally),使代码更具有鲁棒性
+5、记录操作流程和异常:通过logging模块实现
+6、
+7、
+'''
+
+# 内置包
+import os, sys, functools, re, shutil, traceback, time
+import subprocess
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+import logging
+
+# 三方包
+import numpy as np
+from osgeo import gdal
+from ximea import xiapi
+import configparser
+import serial
+import serial.tools.list_ports
+from serial.serialutil import SerialBase, SerialException
+
+# 界面包
+import qimage2ndarray
+from PyQt5.QtCore import Qt, QRectF, pyqtSignal, QObject, QRunnable, pyqtSlot, QThreadPool, QTimer, QT_VERSION_STR
+from PyQt5.QtGui import QPixmap, QImage, QPainterPath
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
+
+from record_system_v24.ui.enter_window import *
+from record_system_v24.ui.image_Window import *
+from record_system_v24.ui.spectral_Window import *
+from record_system_v24.ui.arcus_control_ui import *
+
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.figure import Figure
+
+
+class ArcusWindow(QMainWindow, Ui_arcus_ui):
+ def __init__(self, parent=None):
+ super(ArcusWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ self.left_btn.pressed.connect(self.leftMove)
+ self.left_btn.released.connect(self.stop)
+ self.right_btn.pressed.connect(self.rightMove)
+ self.right_btn.released.connect(self.stop)
+
+
+ # self.speed_lineEdit.setText(self.arc.write('HSPD'))
+ self.speed_lineEdit.textEdited.connect(self.change_speed)
+
+ self.time = time.time() # 控制两次点击后,发送命令的间隔
+
+ def leftMove(self):
+ time_now = time.time()
+ if time_now - self.time > 0.5:
+ self.time = time.time()
+
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J-'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('左移ok!')
+
+ def rightMove(self):
+ time_now = time.time()
+ if time_now - self.time > 0.5:
+ self.time = time.time()
+
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ print(output)
+ # print(error)
+ print('右移ok!')
+
+ def change_speed(self):
+ time_now = time.time()
+ if time_now - self.time > 0.5:
+ self.time = time.time()
+
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py HSPD=' + str(self.speed_lineEdit.text())
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('改变速度ok!')
+
+ def stop(self):
+ self.time = time.time()
+
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py STOP'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('停止ok!')
+
+
+# 主窗口
+class EnterWindow(QMainWindow, Ui_enter_Window):
+ def __init__(self, parent=None):
+ super(EnterWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ # 在刚打开软件在本窗口显示相机状态(是否打开)
+ self.c = Communicate()
+ self.c.openinfo.connect(self.printCamInfo)
+ # self.end_Btn.clicked.connect(self.end_event) # 绑定登陆函数
+ # self.exit_Btn.clicked.connect(sys.exit)
+
+ # self.spectral_mode_bt.clicked.connect(self.spectral_window)
+ self.image_window_instance = ImageWindow()
+ self.image_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.image_mode_bt.clicked.connect(self.image_window_instance.show)
+
+ self.spectral_window_instance = SpectralWindow()
+ self.spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.spectral_mode_bt.clicked.connect(self.spectral_window_instance.show)
+
+ def printCamInfo(self):
+ self.camstatus_tb.append('相机已打开!')
+
+
+# 主窗口信号类
+class Communicate(QObject):
+ openinfo = pyqtSignal()
+ plotsignal = pyqtSignal()
+
+
+class SerialPort(QObject):
+ def __init__(self):
+ super(SerialPort, self).__init__()
+
+ self.logger = logging.getLogger('root.serial')
+
+ formatter1 = logging.Formatter('%(asctime)s %(message)s')
+ temperature_file_handler = logging.FileHandler(os.path.split(__file__)[0] + '//temperature.log') # 输出到文件
+ temperature_file_handler.setLevel(logging.DEBUG)
+ temperature_file_handler.setFormatter(formatter1)
+
+ self.logger.addHandler(temperature_file_handler)
+
+
+
+ # self.signals = pyqtSignal(tuple) # 为啥这就不行呢?
+ self.signals = WorkerSignals()
+
+ self.connect_number = 0 # 记录打开串口的次数
+ self.serial_port = self.open_serial_port()
+
+
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.receiver_data_from_port)
+ self.timer.start(1000)
+
+ def open_serial_port(self):
+ self.connect_number += 1
+ port_list = list(serial.tools.list_ports.comports()) # 列出所有可用串口
+ # print(port_list)
+
+ if len(port_list) > 0: # 如果可用串口 >0 个
+ # 打印出所有串口的信息
+ for i in range(0, len(port_list)):
+ print(port_list[i])
+
+ # 打开第一个串口
+ ser = serial.Serial(port_list[0].device)
+ # print('温湿度传感器打开成功!')
+ return ser
+ elif len(port_list) == 0: # 如果可用串口为0个
+ if self.connect_number == 1:
+ self.logger.info('无可用串口,温湿度传感器不可用!')
+ else:
+ self.logger.error('串口连接上之后,断开连接!')
+ return 1 # 如果返回1,则代表没有可用串口;通过1来判断不执行定时器触发:self.timer.start(1000)
+ else: # 其他没有考虑到的情况
+ return 1
+
+ def receiver_data_from_port(self):
+ '''
+ 定时器QTimer没隔1s调用此函数一次 → 让串口buffer有足够的数据等待读取
+ :return: 无返回值
+
+ 本函数功能:1、串口中接收字节数据,有两种帧 → 代表两种数据
+ 2、判断帧头位置和本帧数据类型
+ 3、判断帧尾 → 等效判断本帧数据是否完全
+ 4、如果数据帧完整 → 解析数据,将温度湿度显示到界面上和写入到文件中
+ '''
+ try:
+ if self.serial_port.in_waiting: # 如果串口buffer有数据等待读取
+ bytes_receive = self.serial_port.read(self.serial_port.inWaiting()) # 读取串口buffer的数据
+ # print(len(bytes_receive))
+
+ # 判断帧头位置,通过正则表达式
+ hex_receive = bytes_receive.hex() # 一个字节需要一个两位16进制数表示,所以:len(hex_receive) = len(bytes_receive) * 2
+ p = re.compile('5a5a*')
+ index_head = [i.start() / 2 for i in re.finditer(p, hex_receive)] # re.finditer()
+ # print(hex_receive)
+ # print(index_head)
+ except SerialException: # 程序打开时,温湿度传感器的串口工作正常;如果程序运行中拔掉串口就会出现此异常
+ self.logger.error('在程序运行中温湿度传感器的串口出现问题!')
+
+ # 再次尝试打开串口
+ self.serial_port = self.open_serial_port()
+ if not isinstance(self.serial_port, int):
+ self.logger.info('再次尝试连接温湿度传感器成功!')
+ else:
+ self.logger.info('再次尝试连接温湿度传感器失败!')
+ except AttributeError: # int object has no attribute: in_waiting
+ self.timer.stop()
+ self.logger.info('停止定时触发器!')
+ except Exception as e: # 未出现过的异常。当第一次出现时,需要编写代码处理,先写入日志文件(log)
+ self.logger.critical('未知错误!')
+ else: # 当没有捕获到异常时,代表串口数据获取成功 → 执行数据解析
+ # 解析数据
+ try:
+ if len(index_head) != 0:
+ Lux = 1.0
+ T = 1.0
+ P = 1.0
+ Hum = 1.0
+ H = 1.0
+ Lux_full = 0 # 判断光照帧的数据是否完整。0:不完整;1:完整;
+ T_full = 0 # 判断温度帧的数据是否完整。0:不完整;1:完整;
+ try:
+ for i in index_head: # 循环遍历每个帧头
+ if bytes_receive[int(i) + 2] == 21: # 0x15=21,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 8]) & 0xff == bytes_receive[int(i) + 8]: # 判断帧尾是否正确
+ # print('光照帧的帧尾正确!')
+
+ Lux_full = 1 # 如果帧尾,此帧数据数完整的
+ Lux = ((bytes_receive[int(i) + 4] << 24) | (bytes_receive[int(i) + 5] << 16) | (
+ bytes_receive[int(i) + 6] << 8) | bytes_receive[int(i) + 7]) / 100
+ if bytes_receive[int(i) + 2] == 69: # 0x45=69,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 14]) & 0xff == bytes_receive[int(i) + 14]: # 判断帧尾是否正确
+ # print('温度帧的帧尾正确!')
+
+ T_full = 1 # 当执行这段代码时,代表帧头帧尾都正常,此帧数据数完整的
+ T = ((bytes_receive[int(i) + 4] << 8) | bytes_receive[int(i) + 5]) / 100
+ P = ((bytes_receive[int(i) + 6] << 24) | (bytes_receive[int(i) + 7] << 16) | (
+ bytes_receive[int(i) + 8] << 8) | bytes_receive[
+ int(i) + 9]) / 100
+ Hum = ((bytes_receive[int(i) + 10] << 8) | bytes_receive[int(i) + 11]) / 100
+ H = ((bytes_receive[int(i) + 12] << 8) | bytes_receive[int(i) + 13]) / 100
+ except IndexError as e: # 当出现帧头,但是帧头到帧尾的数据不全 → 在判断帧尾是否正确时就会出现索引越界
+ # print('----------------------索引越界!')
+ pass
+ except Exception: # 当出现前面没有解决的异常时,前面的异常捕捉就失效。最后通过异常基类来捕捉 → 代表需要修改代码进行处理的新异常
+ # print('---------------------------------没遇见过的异常')
+ pass
+
+ # 将数据显示和写入文件
+ if Lux_full + T_full == 2: # x + y == 2代表温度帧和光照帧都完整
+ # self.t_label.setVisible(True)
+ # self.hum_label.setVisible(True)
+ # self.t_label.setText('温度:' + str(T))
+ # self.hum_label.setText('湿度:' + str(Hum))
+ print('发送数据')
+
+ self.signals.serial.emit((str(T), str(Hum)))
+ self.logger.debug('%s %s', str(T), str(Hum))
+
+ # print('光照强度:%f' % Lux)
+ # print('温度:%f' % T)
+ # print('气压:%f' % P)
+ # print('湿度:%f' % Hum)
+ # print('海拔:%f' % H)
+ # print()
+ elif Lux_full + T_full == 1:
+ # print('只有一个数据帧是完整的。(光照帧或者温度帧)')
+ # print()
+ pass
+ except UnboundLocalError:
+ # print(2222222222222222222222222222222)
+ # traceback.print_exc()
+ pass
+ except Exception:
+ self.logger.critical('未知错误!')
+ finally: # 不管有没有捕获到异常都会执行,一般用作资源回收
+ pass
+
+
+# 图像窗口
+class ImageWindow(QDialog, Ui_image_Window):
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(ImageWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+
+ self.arcus_window_instance = ArcusWindow()
+ self.image_mode_motor_bt.clicked.connect(self.arcus_window_instance.show)
+
+ # log
+ self.logger = logging.getLogger('root.image')
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ image_operate_file_handler = logging.FileHandler("image_operate.log") # 输出到文件
+ image_operate_file_handler.setLevel(logging.INFO)
+ image_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(image_operate_file_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.signals.serial.connect(self.temperature)
+
+ # 采集影像时,边采集边刷新显示
+ # self.plotsignal = pyqtSignal() # 直接这样建立信号执行时会报错
+ self.plotsignal = Communicate()
+ self.plotsignal.plotsignal.connect(self.plotimg)
+
+ #建立进程池
+ # https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ #初始化窗口中的值
+ self.framenumber_le.setText(str(system_setting.frame_number))
+ CameraOperation.framenumber_input = system_setting.frame_number
+ CameraOperation.rgb = np.ones((3, int(system_setting.frame_number), int(
+ (CameraOperation.endColumn - CameraOperation.startColumn) / CameraOperation.bin_spatial)))
+ self.framerate_le.setText(str(system_setting.framerate))
+ self.exposureTime_le.setText(str(system_setting.exposure_time))
+ self.gain_le.setText(str(system_setting.gain))
+ self.filename_le.setText(system_setting.default_image_name)
+ self.filepath_le.setText(system_setting.image_dir)
+
+ # self.framenumber_le.setText(str(CameraOperation.framenumber_input))
+ # self.framerate_le.setText(str(CameraOperation.framerate_input))
+ # self.exposureTime_le.setText(str(CameraOperation.exposureTime_input))
+ # self.gain_le.setText(str(CameraOperation.gain_input))
+ # self.filename_le.setText(system_setting.default_image_name)
+ # self.filepath_le.setText(system_setting.image_dir)
+
+ # #手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ # self.exposureTime_le.textEdited.connect(self.onchange2)
+ # self.exposureTime_le.textChanged.connect(self.onchange)# 将 自动曝光返回到QLineEdit中的值 写入到camera_operation.exposureTime_input
+ # self.gain_le.textEdited.connect(self.onchange2)
+ # self.gain_le.textChanged.connect(self.onchange)# 将 自动曝光返回到QLineEdit中的值 写入到camera_operation.gain_input
+ # self.framerate_le.textEdited.connect(self.onchange2)
+ # self.framenumber_le.textEdited.connect(self.onchange)
+ # self.filename_le.textEdited.connect(self.onchange)
+ # self.filepath_bt.clicked.connect(self.directory_select)
+ # self.filepath_le.textEdited.connect(self.onchange)
+
+ # 显示影像和调焦
+ self.myImageFigure = MyImageFigure()
+ self.image_glo.addWidget(self.myImageFigure)
+ self.myFocusFigure = MySpectralFigureFocus()
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ #操作光谱仪
+ ## 注释的代码没有使用多线程,所以会造成一采集数据界面就卡死的情况
+ # self.focus_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.dc_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.save_bt.clicked.connect(camera_operation.savedata)
+ self.image_mode_exposureTime_bt.clicked.connect(self.run)
+ self.image_mode_focus_bt.clicked.connect(self.run)
+ # 停止调焦和采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_mode_stop_focus_bt.clicked.connect(self.stop_focus)
+ self.image_mode_stop_record_bt.clicked.connect(self.stop_record)
+ self.image_mode_dc_bt.clicked.connect(self.run)
+ self.image_mode_wb_bt.clicked.connect(self.run)
+ self.image_mode_record_bt.clicked.connect(self.run)
+ self.save_bt.clicked.connect(self.save_image)
+
+ # 手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.exposureTime_le.textEdited.connect(self.text_edited)
+ self.gain_le.textEdited.connect(self.text_edited)
+ self.framerate_le.textEdited.connect(self.text_edited)
+ self.framenumber_le.textEdited.connect(self.text_edited)
+ self.filename_le.textEdited.connect(self.text_edited)
+ self.filepath_le.textEdited.connect(self.text_edited)
+
+ self.filepath_bt.clicked.connect(self.directory_select)
+
+ # 手动修改界面中的值后,为相机重新设置如下参数:exposure, gain, framerate
+ def text_edited(self):
+ try:
+ system_setting.exposure_time = int(self.exposureTime_le.text())
+ system_setting.gain = int(float(self.gain_le.text()))
+ system_setting.framerate = int(self.framerate_le.text())
+ system_setting.frame_number = int(self.framenumber_le.text())
+
+ system_setting.signals.image_signal.emit(
+ {'exposure_time': int(self.exposureTime_le.text()), 'gain': int(self.gain_le.text()),
+ 'framerate': int(self.framerate_le.text()), 'frame_number': int(self.framenumber_le.text())})
+ except:
+ traceback.print_exc()
+
+ CameraOperation.set_exposure_gain_framerate(camera)
+
+ CameraOperation.fn = self.filename_le.text()
+
+ CameraOperation.framenumber_input = system_setting.frame_number
+ CameraOperation.rgb = np.ones((3, int(system_setting.frame_number), int(
+ (CameraOperation.endColumn - CameraOperation.startColumn) / CameraOperation.bin_spatial)))
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和system_setting对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ print(result)
+ self.exposureTime_le.setText(str(result[0]))
+ self.gain_le.setText(str(result[1]))
+
+ # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为system_setting.exposure_time的旧值
+ system_setting.exposure_time = result[0]
+ system_setting.gain = result[1]
+
+ try:
+ system_setting.signals.image_signal.emit({'exposure_time': result[0], 'gain': result[1]})
+ except:
+ traceback.print_exc()
+
+ CameraOperation.set_exposure_gain_framerate(camera)
+
+ if result[2] == 1:
+ QMessageBox.information(self, '曝光提示', '光线不足,曝光时间已设置为最大!', QMessageBox.Yes)
+ CameraOperation.autoexposure_feedback = 0
+
+ def temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+ except:
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def timer_start(self):
+ '''
+ 本函数目的是在self.timer.start(1000)外包裹一层(有点装饰器的感觉),加入判断:
+ 1、如果self.serial_port为串口类型,就触发定时器self.timer.start(1000)
+ 2、如果self.serial_port == 1(为int类型),则代表硬件中没有温湿度传感器,就没必要触发定时器self.timer.start(1000)
+ :return: 无返回值
+ '''
+
+ if isinstance(self.serial_port, serial.serialwin32.Serial):
+ self.timer.start(1000)
+ elif isinstance(self.serial_port, int):
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ else:
+ pass
+
+ def plotimg(self):
+ worker = Worker(CameraOperation.plotimg)
+ self.threadpool.start(worker)
+
+ def stop_focus(self):
+ CameraOperation.focus = False
+
+ def stop_record(self):
+ CameraOperation.record = False
+
+ # 调焦、采集暗电流、采集白板、采集影像 都通过此函数
+ def run(self):
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.statu_tb.append('自动曝光...')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.statu_tb.append('调焦...')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.statu_tb.append('采集白板...')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.statu_tb.append('采集影像...')
+
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(CameraOperation.start_AcquireData, camera, self.qt_sender)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.statu_tb.append('自动曝光失败!')
+ self.logger.error('自动曝光失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.statu_tb.append('调焦失败!')
+ self.logger.error('调焦失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.statu_tb.append('采集暗电流失败!')
+ self.logger.error('采集暗电流失败:光谱仪正在工作中,请稍等\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.statu_tb.append('采集白板失败!')
+ self.logger.error('采集白板失败:光谱仪正在工作中,请稍等\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.statu_tb.append('采集影像失败!')
+ self.logger.error('采集影像失败:光谱仪正在工作中,请稍等\n%s', traceback_info[2])
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.statu_tb.append('自动曝光成功!')
+ self.logger.info('自动曝光成功!')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.statu_tb.append('调焦成功!')
+ self.logger.info('调焦成功!')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.statu_tb.append('采集暗电流成功!')
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.statu_tb.append('采集白板成功!')
+ self.logger.info('采集白板成功!')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.statu_tb.append('采集影像成功!')
+ self.logger.info('采集影像成功!')
+
+ def save_image(self):
+ # 操作状态显示
+ self.statu_tb.append('保存影像...')
+
+ worker = Worker(CameraOperation.savedata)
+ self.threadpool.start(worker)
+
+ # 操作状态显示
+ worker.signals.finished.connect(lambda: self.statu_tb.append('保存影像成功!'))
+
+ self.logger.info('保存影像!')
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', '/home')
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.filepath_le.setText(dirpath)
+ system_setting.signals.image_signal.emit({'image_dir': dirpath})
+
+ self.logger.info('选择影像保存路径!')
+
+
+# 光谱窗口
+class SpectralWindow(QDialog, Ui_spectral_Window):
+ def __init__(self, parent=None):
+ super(SpectralWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ # log
+ self.logger = logging.getLogger('root.spectral')
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.signals.serial.connect(self.temperature)
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ spectral_operate_file_handler = logging.FileHandler("spectral_operate.log") # 输出到文件
+ spectral_operate_file_handler.setLevel(logging.INFO)
+ spectral_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(spectral_operate_file_handler)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化值
+ self.filename_le.setText('test')
+ self.filepath_le.setText(os.getcwd())
+
+ #手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filepath_bt.clicked.connect(self.directory_select)
+ self.filename_le.textEdited.connect(self.onchange)
+ self.filepath_le.textEdited.connect(self.onchange)
+
+
+ # 显示光谱和align
+ self.spectralFigure = MySpectralFigureSpectral()
+ self.spe_glo.addWidget(self.spectralFigure)
+ self.alignFigure = MyImageFigure()
+ self.align_glo.addWidget(self.alignFigure)
+
+ #操作光谱仪
+ # self.dc_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ self.spectral_mode_wb_bt.clicked.connect(self.run) # 曝光 + 采集白板
+ self.spectral_mode_align_bt.clicked.connect(self.run)
+ self.spectral_mode_stop_align_bt.clicked.connect(self.stop_align) # 这个操作非常简单,耗时非常短,瞬间可回到event loop;所以不需要多线程
+ self.spectral_mode_dc_bt.clicked.connect(self.run)
+ self.spectral_mode_record_bt.clicked.connect(self.run)
+
+ def temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+ except:
+ traceback.print_exc()
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def stop_align(self):
+ SpectralCameraOperation.align = False
+
+ def run(self):
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.statu_tb.append('曝光/白板...')
+ self.logger.info('曝光/白板...')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.statu_tb.append('align...')
+ self.logger.info('align...')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ self.logger.info('采集暗电流...')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('采集光谱...')
+ self.logger.info('采集光谱...')
+
+ worker = Worker(SpectralCameraOperation.start_AcquireData, camera, self.qt_sender)
+ worker.signals.finished.connect(self.operate_success)
+ worker.signals.error.connect(self.operate_failed)
+ # worker.signals.result.connect()
+
+ self.threadpool.start(worker)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.statu_tb.append('曝光/白板失败!')
+ self.logger.error('曝光/白板失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.statu_tb.append('align 失败!')
+ self.logger.error('align 失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.statu_tb.append('采集暗电流失败!')
+ self.logger.error('采集暗电流失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('采集光谱失败!')
+ self.logger.error('采集光谱失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.statu_tb.append('曝光/白板成功!')
+ self.logger.info('曝光/白板成功!')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.statu_tb.append('align successfully!')
+ self.logger.info('align successfully!')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.statu_tb.append('采集暗电流成功!')
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('采集光谱成功!')
+ self.logger.info('采集光谱成功!')
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ SpectralCameraOperation.fn = self.filename_le.text()
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', '/home')
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.filepath_le.setText(dirpath)
+ system_setting.signals.spectral_signal.emit({'spectral_dir': dirpath})
+ self.logger.info('选择光谱保存路径!')
+
+
+# 画图类,用于:画出采集到的光谱;调焦(影响模式调焦)
+class MySpectralFigureFocus(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ #第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ #第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MySpectralFigureFocus, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ #第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, spectral):
+ self.axes.clear()
+ self.axes.plot(spectral)
+
+
+class MySpectralFigureSpectral(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MySpectralFigureSpectral, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xlabel('Wavelength (nm)')
+ self.axes.set_ylim(0, 1.2)
+ self.axes.set_ylabel('reflectance')
+ #第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, Wavelength, spectral):
+ self.axes.clear()
+ self.axes.set_xlabel('Wavelength (nm)')
+ self.axes.set_ylim(0, 1.2)
+ self.axes.set_ylabel('reflectance')
+ self.axes.plot(Wavelength, spectral)
+
+
+# 画图类,用于:画出采集到的图像;显示帧流(光谱模式对准光纤)
+class MyImageFigure(FigureCanvas):
+ def __init__(self, width=5, height=4, dpi=100):
+ # 第一步:创建一个创建Figure
+ self.fig = Figure(figsize=(width, height), dpi=dpi)
+ # 第二步:在父类中激活Figure窗口
+ # this is the Canvas Widget that displays the `figure`
+ # it takes the `figure` instance as a parameter to __init__
+ super(MyImageFigure, self).__init__(self.fig) # 此句必不可少,否则不能显示图形
+ # 第三步:创建一个子图,用于绘制图形用,111表示子图编号,如matlab的subplot(1,1,1)
+ self.axes = self.fig.add_subplot(1, 1, 1)
+ self.axes.set_xticks([])
+ self.axes.set_yticks([])
+ # 第四步:就是画图,【可以在此类中画,也可以在其它类中画】
+ def plot(self, frame):
+ self.axes.clear()
+ self.axes.set_xticks([])
+ self.axes.set_yticks([])
+ self.axes.imshow(frame)
+
+
+class WorkerSignals(QObject):
+ '''
+ Defines the signals available from a running worker thread.
+
+ Supported signals are:
+
+ finished
+ No data
+
+ error
+ `tuple` (exctype, value, traceback.format_exc() )
+
+ result
+ `object` data returned from processing, anything
+
+ progress
+ `int` indicating % progress
+
+ '''
+ finished = pyqtSignal()
+ error = pyqtSignal(tuple)
+ result = pyqtSignal(object)
+ progress = pyqtSignal(int) # 可以用作进度条
+
+ serial = pyqtSignal(object)
+
+ image_signal = pyqtSignal(dict)
+ spectral_signal = pyqtSignal(dict)
+
+
+# https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+# 用于qt多线程:运行long-time task
+class Worker(QRunnable):
+ '''
+ Worker thread
+
+ Inherits from QRunnable to handler worker thread setup, signals and wrap-up.
+
+ :param callback: The function callback to run on this worker thread. Supplied args and
+ kwargs will be passed through to the runner.
+ :type callback: function
+ :param args: Arguments to pass to the callback function
+ :param kwargs: Keywords to pass to the callback function
+
+ '''
+
+ def __init__(self, fn, *args, **kwargs):
+ super(Worker, self).__init__()
+
+ # Store constructor arguments (re-used for processing)
+ self.fn = fn
+ self.args = args
+ self.kwargs = kwargs
+ self.signals = WorkerSignals()
+
+ # Add the callback to our kwargs
+ # self.kwargs['progress_callback'] = self.signals.progress
+
+ @pyqtSlot()
+ def run(self):
+ '''
+ Initialise the runner function with passed args, kwargs.
+ '''
+ try:
+ result = self.fn(*self.args, **self.kwargs)
+ except Exception:
+ exctype, value = sys.exc_info()[:2]
+ self.signals.error.emit((exctype, value, traceback.format_exc()))
+ else:
+ self.signals.finished.emit() # Done
+ self.signals.result.emit(result) # Return the result of the processing
+ finally:
+ pass
+
+
+# 读写影像类
+class Grid(object):
+
+ #读图像文件
+ @classmethod
+ def read_img(cls, filename, xoff=0, yoff=0, im_width=None, im_height=None):
+ try:
+ dataset = gdal.Open(filename) # 打开文件
+ if im_width == None:
+ im_width = dataset.RasterXSize # 栅格矩阵的列数
+ if im_height == None:
+ im_height = dataset.RasterYSize # 栅格矩阵的行数
+ num_bands = dataset.RasterCount # 栅格矩阵的波段数
+ im_geotrans = dataset.GetGeoTransform() # 仿射矩阵
+ im_proj = dataset.GetProjection() # 地图投影信息
+ im_data = dataset.ReadAsArray(xoff, yoff, im_width, im_height) # 将数据写成数组,对应栅格矩阵
+ del dataset
+ return im_proj, im_geotrans, im_data
+ except:
+ sys.exit()
+
+ #写文件,以写成tif为例
+ @classmethod
+ def write_img(cls, dst_filename, data):
+ format = "ENVI"
+ driver = gdal.GetDriverByName(format)
+ RasterXSize = data.shape[2] # 遥感影像的sample(列数)
+ RasterYSize = data.shape[1] # 遥感影像的line(行数)
+ band = data.shape[0]
+ # driver.Create()函数中RasterXSize代表影像的sample(列数),RasterYSize代表影像的line(行数)
+ dst_ds = driver.Create(dst_filename, RasterXSize, RasterYSize, band, gdal.GDT_Float32)
+ for i in range(band):
+ dst_ds.GetRasterBand(i + 1).WriteArray(data[i, :, :]) # gdal的band从1开始,所以dst_ds.GetRasterBand(i+1)
+ dst_ds = None
+
+
+# 影像模式类:相关的函数和变量
+class CameraOperation(object):
+
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1649
+
+ # 转辐亮度
+ rad_or_not = False
+ img_gain = r'D:\py_program\corning410\corning410_radiance_calibration\jfq_dn_gain'
+ _, _, gain = Grid.read_img(img_gain)
+ gain = gain.astype(np.float)
+ cal_it = 6059
+ target_it = None
+ gain_scale = None
+
+ @classmethod
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposure_gain_framerate(cls, cam):
+ # settings,cam.set_param("exposure",10000)
+ cam.set_framerate(int(system_setting.framerate))
+ cam.set_exposure(int(system_setting.exposure_time)) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(int(float(system_setting.gain))) #int('0.0')会报错,int(float('0.0'))不会报错
+
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ # ('Framerate: ' + str(cam.get_framerate()) + ' FPS')这样连接字符串会浪费内存
+ enter_window_instance.image_window_instance.statu_tb.append("%s%s%s" % ('Framerate: ', str(cam.get_framerate()), ' FPS'))
+ enter_window_instance.image_window_instance.statu_tb.append("%s%s%s" % ('Exposure: ', str(cam.get_exposure()), ' us'))
+ enter_window_instance.image_window_instance.statu_tb.append("%s%s%s" % ('Gain: ', str(cam.get_gain()), ' dB'))
+
+ # 开始采集数据
+ framenumber_input = 100 # 随便给个初始值(初始值要和framenumber_le控件初始值一致),从image_window获取的手动输入的帧数
+ image_dc = 1 # 随便给个初始值,此变量用于存储采集到的暗电流影像
+ image_wb = 1 # 随便给个初始值,此变量用于存储采集到的白板影像
+ focus = True # 用于停止调焦
+ record = True # 用于停止采集
+ img_datatype = 12 # 在头文件中确定影像数据类型
+ # bin相关设置
+ bin_spectral = 1 # 光谱bin
+ bin_spatial = 1 # 空间bin
+ k = np.arange(endRow - startRow)[0::bin_spectral]
+ l = np.arange(endColumn - startColumn)[0::bin_spatial]
+
+ rgb = np.zeros((3, int(framenumber_input), int((endColumn - startColumn) / bin_spatial)))
+
+ autoexposure_feedback = 0 # 指示:自动曝光所得到的shutter值是否为最大;如果为最大→值设置为1
+ @classmethod
+ def start_AcquireData(cls, cam, qt_sender): # qt_sender是指qt窗口中事件的发生者
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ # 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+ # 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype(' int(1 / int(system_setting.framerate) * 10**6):
+ cam.set_exposure(int(1 / int(system_setting.framerate) * 10**6))
+ cls.autoexposure_feedback = 1
+
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 如果点击“调焦”按钮
+ if qt_sender == 'image_mode_focus_bt':
+ # cls.set_exposureTime(cam)
+
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not cls.focus:
+ cls.focus = True
+
+ cam.start_acquisition()
+
+ while cls.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ enter_window_instance.image_window_instance.myImageFigure.plot(image_container)
+ enter_window_instance.image_window_instance.myImageFigure.draw()
+ enter_window_instance.image_window_instance.myFocusFigure.plot(image_container[150, :])
+ enter_window_instance.image_window_instance.myFocusFigure.draw()
+
+ # 如果点击“白板”按钮,采集并保存白板影像到image_wb
+ if qt_sender == 'image_mode_wb_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ # 白板扣除暗电流放在暗电流采集中
+ cls.image_wb = image_container_bin
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'image_mode_dc_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ cls.image_dc = image_container_bin
+ cls.image_wb = cls.image_wb - cls.image_dc
+
+ # 如果点击“采集”按钮,自动去除暗电流,并且转化成反射率
+ if qt_sender == 'image_mode_record_bt':
+ frameCount = 1 # 统计采集的帧数,用于停止采集使用
+
+ # 当停止采集后,再次开始采集需要将cls.record的值从False变为True
+ if not cls.record:
+ cls.record = True
+
+ # 开始马达
+ try:
+ # D:\py27_program\arcus\ArcusDevice.py
+ python2_command = r'D:\software\Anaconda3\envs\py27_32\python2.exe ' + os.path.dirname(__file__) + '/ArcusDevice.py' + ' CLR PX=0 EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+ except:
+ pass
+
+
+ # 开始采集数据 并且 将数据写入到硬盘中
+ cam.start_acquisition()
+ with open('corning410_test', 'wb') as f:
+
+ print('Starting data acquisition...')
+ startTime = datetime.datetime.now()
+
+ while cls.record:
+ cam.get_image(img) # get data and pass them from camera to img
+ # image_raw_numpy.dtype -> dtype(' maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+ else: # 对于彩色照片,需要先单独对每个波段拉伸
+ img_new = np.empty(img.shape)
+ for i in range(img.shape[2]):
+ low = np.percentile(img[:, :, i], lowPercentile)
+ up = np.percentile(img[:, :, i], highPercentile)
+
+ img_new[:, :, i] = minout + ((img[:, :, i] - low) / (up - low)) * (maxout - minout)
+ img_new[:, :, i][img_new[:, :, i] < minout] = minout
+ img_new[:, :, i][img_new[:, :, i] > maxout] = maxout
+ img_out = np.uint8(img_new)
+ return img_out
+
+ @classmethod
+ def close_camera(cls, cam):
+ # stop communication
+ cam.close_device()
+
+
+# 光谱模式类:相关的函数和变量
+class SpectralCameraOperation(object):
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1649
+
+ # 转辐亮度
+ rad_or_not = False
+ img_gain = r'D:\py_program\corning410\corning410_radiance_calibration\jfq_dn_gain'
+ _, _, gain = Grid.read_img(img_gain)
+ gain = gain.astype(np.float)
+ cal_it = 6059
+ target_it = None
+ gain_scale = None
+
+ # 开始采集数据
+ fn = 'test' # 随便给个初始值(初始值要和filename_le控件初始值一致),从spectral_window获取的手动输入的帧率
+
+ framenumber = 10 # 每条光谱为多少帧平均得到
+ spectral_container = np.empty((endRow - startRow, framenumber, endColumn - startColumn)).astype(np.float)
+ # spectral_container = np.empty((300, framenumber, 3)).astype(np.float64)
+
+ align = True # 用于对准光纤
+ image_dc = np.empty((endRow - startRow, endColumn - startColumn)).astype(np.float) # 此变量用于存储采集到的暗电流,一帧平均得到
+ spectralNumber_wb = 1 # 每次采集的白板的光谱数
+ spectral_wb = np.empty((endRow - startRow, endColumn - startColumn)).astype(np.float) # 此变量用于存储采集到的白板,一帧平均得到
+ spectral_wb_tmp = np.empty((endRow - startRow, framenumber, endColumn - startColumn)) # 此变量用于存储采集到的白板原始一帧影像,后面白板影像去除了暗电流后值赋给spectral_wb
+ spectralNumber = 10 # 每次采集目标物的光谱数
+ spectral = np.empty((endRow - startRow, spectralNumber)).astype(np.float) # 此ndarray用于存储采集到的目标物光谱,每一列为一个光谱
+
+ @classmethod
+ def start_AcquireData(cls, cam, qt_sender):
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ cam.set_imgdataformat('XI_RAW16')
+ # create instance of Image to store image data and metadata
+ img = xiapi.Image()
+
+ print('Starting data acquisition...')
+ starttime = datetime.datetime.now()
+
+ # 如果点击暗“align”按钮
+ if qt_sender == 'spectral_mode_align_bt':
+
+ if not cls.align:
+ cls.align = True
+
+ cam.start_acquisition()
+ while cls.align:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ enter_window_instance.spectral_window_instance.alignFigure.plot(image_raw_numpy)
+ enter_window_instance.spectral_window_instance.alignFigure.draw()
+
+ # 如果点击“曝光/白板”按钮:(1)先自动曝光;(2)然后在采集白板
+ if qt_sender == 'spectral_mode_wb_bt':
+
+ # 自动曝光
+ cam.set_framerate(15)
+ cam.set_aeag_roi_offset_x(cls.startColumn)
+ cam.set_aeag_roi_offset_y(cls.startRow)
+ cam.set_aeag_roi_height(cls.endRow - cls.startRow)
+ cam.set_aeag_roi_width(cls.endColumn - cls.startColumn)
+ # cam.set_exp_priority(1) # Exposure priority (0.8 - exposure 80%, gain 20%).XI_PRM_EXP_PRIORITY
+ # cam.set_ae_max_limit(24000) # Maximum time (us) used for exposure in AEAG procedureXI_PRM_AE_MAX_LIMIT
+ # cam.set_ag_max_limit(12)
+ # cam.set_aeag_level(50) # Average intensity of output signal AEAG should achieve(in %)XI_PRM_AEAG_LEVEL
+ # 还有两个不知怎么用的参数:XI_PRM_GAIN_SELECTOR or "gain_selector"和XI_PRM_SHUTTER_TYPE or "shutter_type"
+ cam.enable_aeag()
+ cam.start_acquisition()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ cam.disable_aeag()
+
+ # 将自动曝光获得的exposure和gain写入到相机
+ cam.set_framerate(15)
+ cam.set_exposure(cam.get_exposure())
+ cam.set_gain(cam.get_gain())
+ enter_window_instance.spectral_window_instance.statu_tb.append('Exposure: ' + str(cam.get_exposure()) + ' us')
+ enter_window_instance.spectral_window_instance.statu_tb.append('Framerate: ' + str(cam.get_framerate()) + ' FPS')
+
+ # 计算gain
+ cls.target_it = cam.get_exposure()
+ cls.gain_scale = cls.cal_it / cls.target_it
+ cls.gain = cls.gain * cls.gain_scale
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 开始采集白板数据,去除白板暗电流的操作放在采集暗电流时进行
+ cam.start_acquisition()
+ for i in range(cls.framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow,
+ cls.startColumn:cls.endColumn]
+
+ # 去除白板暗电流的操作放在采集暗电流时进行
+ # cls.spectral_container没经过运算,传给cls.spectral_wb_tmp的是cls.spectral_container的内存地址
+ cls.spectral_wb_tmp = cls.spectral_container
+
+ # 存储原始白板影像
+ filename = system_setting.spectral_dir + '\\' + 'baiban'
+ with open(filename, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_wb_tmp[:, i, :].flatten().tobytes())
+ CameraOperation.write_hdr(filename, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # 如果点击暗“暗电流”按钮
+ if qt_sender == 'spectral_mode_dc_bt':
+ # 为cls.spectral_container新建立一个内存地址,以免改变cls.spectral_wb_tmp(传址)的值
+ cls.spectral_container = np.empty((cls.endRow - cls.startRow, cls.framenumber, cls.endColumn - cls.startColumn))
+ cam.start_acquisition()
+ for i in range(cls.framenumber): # 此循环为啥会改变649行的赋值的结果呢?怎么会执行那里的代码
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow, cls.startColumn:cls.endColumn]
+
+ # 存储暗电流影像
+ filename1 = system_setting.spectral_dir + '\\' + 'dark'
+ with open(filename1, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ CameraOperation.write_hdr(filename1, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # cls.spectral_container经过运算,传给cls.image_dc的不是cls.spectral_container的内存地址,是新运算结果的内存地址;相当于传值
+ cls.image_dc = cls.spectral_container.mean(axis=1) # 因为平均,cls.image_dc的数据类型为:dtype('float')
+
+ # 去除白板暗电流
+ for i in range(cls.framenumber):
+ cls.spectral_wb_tmp[:, i, :] = cls.spectral_wb_tmp[:, i, :] - cls.image_dc
+
+ # 存储扣除暗电流的白板影像
+ filename2 = system_setting.spectral_dir + '\\' + 'baiban_rmdark'
+ with open(filename2, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_wb_tmp[:, i, :].flatten().tobytes())
+ CameraOperation.write_hdr(filename2, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # 决定是否将白板转化成辐亮度
+ if cls.rad_or_not:
+ cls.spectral_wb = cls.spectral_wb_tmp.mean(axis=1) * cls.gain[:, 0, :]
+ else:
+ cls.spectral_wb = cls.spectral_wb_tmp.mean(axis=1) # 因为平均,cls.spectral_wb的数据类型为:dtype('float')
+
+
+ # 如果点击“采集”按钮,去除暗电流,转化成反射率,
+ if qt_sender == 'spectral_mode_record_bt':
+ cam.start_acquisition()
+ for j in range(cls.spectralNumber):
+ for i in range(cls.framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ cls.spectral_container[:, i, :] = image_raw_numpy[cls.startRow:cls.endRow,
+ cls.startColumn:cls.endColumn]
+
+ # 存储扣除暗电流前的目标物影像
+ if j == 1:
+ filename1 = system_setting.spectral_dir + '\\' + cls.fn
+ with open(filename1, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ CameraOperation.write_hdr(filename1, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ for i in range(cls.framenumber): # (1)去除暗电流;(2)转辐亮度;(3)转反射率
+ if cls.rad_or_not:
+ cls.spectral_container[:, i, :] = (cls.spectral_container[:, i,
+ :] - cls.image_dc) * cls.gain[:, 0, :] / cls.spectral_wb
+ else:
+ cls.spectral_container[:, i, :] = (cls.spectral_container[:, i,
+ :] - cls.image_dc) / cls.spectral_wb
+
+ # 存储目标物反射率影像
+ if j == 1:
+ filename2 = system_setting.spectral_dir + '\\' + cls.fn + '_ref'
+ with open(filename2, 'wb') as f:
+ for i in range(cls.framenumber):
+ f.write(cls.spectral_container[:, i, :].flatten().tobytes())
+ CameraOperation.write_hdr(filename2, cls.framenumber, cam.get_exposure(), cam.get_framerate())
+
+ # spectral_tmp = cls.spectral_container.sum(axis=1).sum(axis=1)
+ spectral_tmp = cls.spectral_container.mean(axis=1).mean(axis=1)
+
+ cls.spectral[:, j] = spectral_tmp
+
+ # 画出光谱
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+ wavelength = np.empty(cls.endRow - cls.startRow)
+ for i in range(cls.startRow, cls.endRow):
+ wavelength[i - cls.startRow] = calculate_wavelength(i)
+ enter_window_instance.spectral_window_instance.spectralFigure.plot(wavelength, spectral_tmp)
+ enter_window_instance.spectral_window_instance.spectralFigure.draw()
+
+ # 计算波长
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+ wavelength = np.empty(cls.endRow - cls.startRow)
+ for i in range(cls.startRow, cls.endRow):
+ wavelength[i - cls.startRow] = calculate_wavelength(i)
+
+ # 保存光谱为txt文件
+ cls.spectral = np.insert(cls.spectral, 0, wavelength, axis=1)
+ for i in range(cls.spectralNumber):
+ np.savetxt(system_setting.spectral_dir + '\\' + cls.fn + str(i) + '.txt', cls.spectral[:, [0, i + 1]], fmt='%f')
+
+ endtime = datetime.datetime.now()
+ print('光谱采集用时:%d' % (endtime - starttime).seconds)
+
+ # stop data acquisition
+ print('Stopping acquisition...')
+ cam.stop_acquisition()
+
+ @classmethod
+ def close_camera(cls, cam):
+ # stop communication
+ cam.close_device()
+
+
+# 相机参数设置
+class SystemSetting(object):
+ def __init__(self):
+ self.file_dir = os.path.split(__file__)[0]
+ self.corning_config_file = self.file_dir + '//corning_config.ini'
+
+ self.signals = WorkerSignals()
+ self.signals.image_signal.connect(self.image_record_param_changed)
+ self.signals.spectral_signal.connect(self.spectral_record_param_changed)
+
+ self.read_config_file()
+ self.open_camera()
+ self.set_binning()
+ self.log()
+
+ # 读取配置文件,如果没有就创建
+ def read_config_file(self):
+ if os.path.exists(self.corning_config_file):
+ '''
+ 如果存在配置文件,就从配置文件中读取软件配置信息
+ '''
+ print('配置文件存在!')
+
+ config = configparser.ConfigParser()
+ config.read(self.corning_config_file)
+
+ self.image_dir = config.get('image_record_param', 'image_dir')
+ self.create_directory(self.image_dir)
+ self.default_image_name = config.get('image_record_param', 'default_image_name')
+ self.framerate = int(config.get('image_record_param', 'framerate'))
+ self.exposure_time = int(config.get('image_record_param', 'exposure_time'))
+ self.gain = int(float(config.get('image_record_param', 'gain')))
+ self.frame_number = int(config.get('image_record_param', 'frame_number'))
+
+ self.spectral_dir = config.get('spectral_record_param', 'spectral_dir')
+ self.create_directory(self.spectral_dir)
+ self.default_spectral_name = config.get('spectral_record_param', 'default_spectral_name')
+
+ self.binning = int(config.get('bin', 'binning'))
+ if self.binning == 1:
+ self.start_column = int(config.get('bin', 'start_column_binning_1'))
+ self.end_column = int(config.get('bin', 'end_column_binning_1'))
+ self.start_row = int(config.get('bin', 'start_row_binning_1'))
+ self.end_row = int(config.get('bin', 'end_row_binning_1'))
+ elif self.binning == 2:
+ self.start_column = int(config.get('bin', 'start_column_binning_2'))
+ self.end_column = int(config.get('bin', 'end_column_binning_2'))
+ self.start_row = int(config.get('bin', 'start_row_binning_2'))
+ self.end_row = int(config.get('bin', 'end_row_binning_2'))
+
+ # print(self.default_dir, self.binning, self.start_column, self.end_column, self.start_row, self.end_row)
+
+ else:
+ '''
+ 1、如果不存在配置文件,就建立配置文件;
+ 2、并且手动创建配置变量
+ '''
+ config = configparser.ConfigParser()
+
+ # config.add_section('effective_window')
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1649
+
+
+ config.add_section('bin')
+ config.set('bin', 'binning', '1')
+
+ config.set('bin', 'start_column_binning_1', '12')
+ config.set('bin', 'end_column_binning_1', '1376')
+ config.set('bin', 'start_row_binning_1', '1')
+ config.set('bin', 'end_row_binning_1', '300')
+
+ config.set('bin', 'start_column_binning_2', '13')
+ config.set('bin', 'end_column_binning_2', '695')
+ config.set('bin', 'start_row_binning_2', '1')
+ config.set('bin', 'end_row_binning_2', '150')
+
+ config.add_section('image_record_param')
+ config.set('image_record_param', 'image_dir', self.file_dir + '/image')
+ config.set('image_record_param', 'default_image_name', 'test_image')
+ config.set('image_record_param', 'framerate', '20')
+ config.set('image_record_param', 'exposure_time', '500')
+ config.set('image_record_param', 'gain', '0')
+ config.set('image_record_param', 'frame_number', '20')
+
+ config.add_section('spectral_record_param')
+ config.set('spectral_record_param', 'spectral_dir', self.file_dir + '/spectral')
+ config.set('spectral_record_param', 'default_spectral_name', 'test_spectral')
+ # config.set('spectral_record_param', 'start_column_binning_1', '12')
+
+ with open(self.corning_config_file, mode='w') as f:
+ config.write(f)
+ print('创建配置文件成功!')
+
+ # 如果没有配置文件,就手动创建配置变量
+ self.image_dir = self.file_dir + '/image'
+ self.create_directory(self.image_dir)
+ self.default_image_name = 'test_image'
+ self.framerate = 20
+ self.exposure_time = 500
+ self.gain = 0
+ self.frame_number = 20
+
+ self.spectral_dir = self.file_dir + '/spectral'
+ self.create_directory(self.spectral_dir)
+ self.default_spectral_name = 'test_spectral'
+
+ self.binning = 1
+ self.start_column = int(config.get('bin', 'start_column_binning_1'))
+ self.end_column = int(config.get('bin', 'end_column_binning_1'))
+ self.start_row = int(config.get('bin', 'start_row_binning_1'))
+ self.end_row = int(config.get('bin', 'end_row_binning_1'))
+
+ # self.start_column = 12
+ # self.end_column = 1376
+ # self.start_row = 1
+ # self.end_row = 300
+
+ # 打开相机
+ def open_camera(self):
+ # create instance for first connected camera
+ self.cam = xiapi.Camera()
+
+ # start communication to open specific device, use: cam.open_device_by_SN('41305651')
+ print('Opening first camera...')
+ self.cam.open_device()
+
+ # 打开相机后,显示相机信息
+ print('SN: %s' % str(self.cam.get_device_sn(), encoding="utf-8"))
+ print('Device name: %s' % str(self.cam.get_device_name(), encoding="utf-8"))
+ print('Device name: %s' % str(self.cam.get_device_type(), encoding="utf-8"))
+ print('Instance path: %s' % str(self.cam.get_device_inst_path(), encoding="utf-8")) # Returns device instance path in operating system.
+ print('Location path: %s' % str(self.cam.get_device_loc_path(), encoding="utf-8"))
+ print('Debug level: %s' % self.cam.get_debug_level())
+
+ # The number of threads per image processor
+ print('Default number of threads per image processor: %d' % self.cam.get_proc_num_threads())
+ self.cam.set_proc_num_threads(8)
+ print('Current number of threads per image processor: %d' % self.cam.get_proc_num_threads())
+
+ # 图像水平翻转
+ print('Is horizontal flip enabled?, %s' % str(self.cam.is_horizontal_flip()))
+ print()
+
+ # This mode is supported by selected camera families: CB, MC, MT, MX
+ self.cam.set_acq_timing_mode('XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ mode_used = self.cam.get_acq_timing_mode()
+ if mode_used == 'XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT':
+ print('Mode is XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ else:
+ print('Mode is not XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ sys.exit()
+
+ #
+ def set_binning(self):
+ self.cam.set_binning_selector('XI_BIN_SELECT_HOST_CPU') # 默认为XI_BIN_SELECT_SENSOR(会报错),不可用:XI_BIN_SELECT_DEVICE_FPGA
+ self.cam.set_binning_horizontal_mode('XI_BIN_MODE_SUM')
+ self.cam.set_binning_horizontal(self.binning)
+ self.cam.set_binning_vertical_mode('XI_BIN_MODE_SUM')
+ self.cam.set_binning_vertical(self.binning)
+
+ # 返回打开的相机对象
+ def get_cam(self):
+ return self.cam
+
+ # 查看是否存在保存光谱和影像文件的目录,如果没有就创建
+ def create_directory(self, dir):
+ if not os.path.exists(dir):
+ print('创建文件夹:%s', dir)
+ os.makedirs(dir)
+
+ def log(self):
+ # 判断是否存在log文件,如果不存在就创建
+ if not os.path.exists(self.file_dir + '//all_operate.log'):
+ with open(self.file_dir + '//all_operate.log', 'w') as f:
+ pass
+ if not os.path.exists(self.file_dir + '//image_operate.log'):
+ with open(self.file_dir + '//image_operate.log', 'w') as f:
+ pass
+ if not os.path.exists(self.file_dir + '//spectral_operate.log'):
+ with open(self.file_dir + '//spectral_operate.log', 'w') as f:
+ pass
+ if not os.path.exists(self.file_dir + '//error.log'):
+ with open(self.file_dir + '//error.log', 'w') as f:
+ pass
+ if not os.path.exists(self.file_dir + '//temperature.log'):
+ with open(self.file_dir + '//temperature.log', 'w') as f:
+ pass
+
+ # 初始化log
+ root_logger = logging.getLogger('root')
+ root_logger.setLevel(level=logging.DEBUG) # logger级别设置为低级别,代表这个logger可以处理很多级别的日志,更灵活的处理放在logger中的各种handler中
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+
+ all_operate_file_handler = logging.FileHandler(self.file_dir + '//all_operate.log') # 输出到文件
+ all_operate_file_handler.setLevel(logging.INFO)
+ all_operate_file_handler.setFormatter(formatter)
+
+ error_file_handler = logging.FileHandler(self.file_dir + '//error.log') # 输出到文件
+ error_file_handler.setLevel(logging.ERROR)
+ error_file_handler.setFormatter(formatter)
+
+ stream_handler = logging.StreamHandler() # 输出到控制台
+ stream_handler.setLevel(logging.INFO)
+ stream_handler.setFormatter(formatter)
+
+ root_logger.addHandler(all_operate_file_handler)
+ root_logger.addHandler(error_file_handler)
+ root_logger.addHandler(stream_handler)
+
+ def image_record_param_changed(self, dictionary):
+ '''
+ :param dictionary: {'image_dir':值, 'image_record_param': 值}
+ :return:
+ '''
+ try:
+ print(len(dictionary.keys()))
+
+ config = configparser.ConfigParser()
+ config.read(self.corning_config_file)
+
+
+ for key in dictionary.keys():
+ if key == 'image_dir':
+ self.image_dir = dictionary[key]
+ config.set('image_record_param', key, dictionary[key])
+ if key == 'framerate':
+ self.framerate = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'exposure_time':
+ self.exposure_time = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'gain':
+ self.gain = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ if key == 'frame_number':
+ self.frame_number = dictionary[key]
+ config.set('image_record_param', key, str(dictionary[key]))
+ except:
+ traceback.print_exc()
+
+ with open(self.corning_config_file, 'w') as f:
+ config.write(f)
+
+ def spectral_record_param_changed(self, dictionary):
+ '''
+ :param dictionary: {'image_dir':值, 'image_record_param': 值}
+ :return:
+ '''
+ print(len(dictionary.keys()))
+
+ config = configparser.ConfigParser()
+ config.read(self.corning_config_file)
+
+ try:
+ for key in dictionary.keys():
+ if key == 'spectral_dir':
+ self.spectral_dir = dictionary[key]
+ config.set('spectral_record_param', key, dictionary[key])
+ # if key == 'default_spectral_name':
+ # self.framerate = dictionary[key]
+ # config.set('spectral_record_param', key, dictionary[key])
+ except:
+ traceback.print_exc()
+
+ with open(self.corning_config_file, 'w') as f:
+ config.write(f)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ system_setting = SystemSetting()
+ camera = system_setting.get_cam()
+
+ serial_port = SerialPort()
+
+ # 实例化窗口
+ enter_window_instance = EnterWindow()
+ enter_window_instance.c.openinfo.emit()
+ enter_window_instance.show()
+
+ sys.exit(app.exec_())
diff --git a/record_system_v24/ArcusDevice.py b/record_system_v24/ArcusDevice.py
new file mode 100644
index 0000000..70ba5a0
--- /dev/null
+++ b/record_system_v24/ArcusDevice.py
@@ -0,0 +1,75 @@
+"""
+Arcus controller python interface.
+Only works if one ARCUS device is connected.
+Including Arcus Configuration cables.
+Open ArcusDevice.py in Python IDE --> Run --> Enter Terminal Commands
+"""
+import threading
+import Arcus
+import copy
+import sys
+
+class ArcusDevice(object):
+ """
+ This is interface class to Arcus stepper controller
+ @author Lukas Zubal
+ @version 1.0
+ """
+ def __init__(self):
+ """
+ @brief Constructor
+ @param self object instance
+ """
+ self.device = Arcus.Arcus()
+ if self.device.Connect() == 1:
+ print ' '
+ else:
+ print "Cannot open stepper device on port "
+ sys.exit()
+ self.outputBuffer = " "
+ self.lock = threading.Lock() # thread safety
+ self.verbose = 0
+
+ def close(self):
+ """
+ @brief Closes Arcus device connection
+ @param self object instance
+ @return bool Returns a 1 if successful
+ """
+ self.lock.acquire()
+ self.device.Close()
+ self.lock.release()
+ del self.device
+ return 1
+
+ def write(self, data):
+ """
+ @brief Command-response call to Arcus device
+ @see Arcus controller manual for complete list of interactive commands
+ @param self object instance
+ @param data string containing interactive commands to arcus
+ @return str Returns string containing response of controller
+ """
+ self.lock.acquire()
+ self.device.SendAndRecive(data, self.outputBuffer)
+ resp = copy.deepcopy(self.outputBuffer[:])
+ self.lock.release()
+ resp = resp.split('\x00')[0]
+ if self.verbose == 1:
+ print resp
+ return resp
+
+arc = ArcusDevice()
+
+arc.write('DN') # Send Terminal Command to return device name.
+# print "Connected to device: " + response # Notify user
+
+for i in range(len(sys.argv)-1):
+ response = arc.write(sys.argv[i+1]) # Process Command and save Controller Response
+ while response != 'OK':
+ response = arc.write(sys.argv[i+1])
+ if sys.argv[i+1] == 'HSPD':
+ print response
+
+arc.close() # Close Device.
+del arc
diff --git a/record_system_v24/corning_config.ini b/record_system_v24/corning_config.ini
new file mode 100644
index 0000000..23e9a90
--- /dev/null
+++ b/record_system_v24/corning_config.ini
@@ -0,0 +1,23 @@
+[bin]
+binning = 1
+start_column_binning_1 = 12
+end_column_binning_1 = 1376
+start_row_binning_1 = 1
+end_row_binning_1 = 300
+start_column_binning_2 = 13
+end_column_binning_2 = 695
+start_row_binning_2 = 1
+end_row_binning_2 = 150
+
+[image_record_param]
+image_dir = D:/07 Itres
+default_image_name = test_image
+framerate = 60
+exposure_time = 16667
+gain = 0.0
+frame_number = 600
+
+[spectral_record_param]
+spectral_dir = D:/demo data
+default_spectral_name = test_spectral
+
diff --git a/record_system_v24/delete.py b/record_system_v24/delete.py
new file mode 100644
index 0000000..e08a96b
--- /dev/null
+++ b/record_system_v24/delete.py
@@ -0,0 +1,42 @@
+import os, subprocess, time, traceback
+
+print('开始马达')
+try:
+ # D:\software\Anaconda3\envs\py27_32\
+ python2_command = r'python2.exe ' + os.path.dirname(__file__) + '/ArcusDevice.py' + ' CLR PX=0 EO=1 J+'
+ print(python2_command)
+ print(python2_command.split())
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ print('有错1')
+ process.kill()
+ output, error = process.communicate()
+except:
+ traceback.print_exc()
+ print('有错2')
+ pass
+
+
+print('转动5秒')
+time.sleep(5)
+
+
+print('返回马达')
+try:
+ # D:\software\Anaconda3\envs\py27_32\
+ # 打包:https://stackoverflow.com/questions/58995937/using-pyinstaller-to-convert-python3-and-python2-to-exe
+ python2_command = r'python2.exe ' + os.path.dirname(__file__) + '/ArcusDevice.py' + ' CLR STOP X0'
+ print(python2_command)
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ print('有错3')
+ process.kill()
+ output, error = process.communicate()
+except:
+ traceback.print_exc()
+ print('有错4')
+ pass
diff --git a/record_system_v24/ui/__init__.py b/record_system_v24/ui/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/record_system_v24/ui/arcus_control_ui.py b/record_system_v24/ui/arcus_control_ui.py
new file mode 100644
index 0000000..640777f
--- /dev/null
+++ b/record_system_v24/ui/arcus_control_ui.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'arcus_control_ui.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_arcus_ui(object):
+ def setupUi(self, arcus_ui):
+ arcus_ui.setObjectName("arcus_ui")
+ arcus_ui.resize(354, 171)
+ self.centralwidget = QtWidgets.QWidget(arcus_ui)
+ self.centralwidget.setObjectName("centralwidget")
+ self.left_btn = QtWidgets.QPushButton(self.centralwidget)
+ self.left_btn.setGeometry(QtCore.QRect(100, 90, 61, 21))
+ self.left_btn.setObjectName("left_btn")
+ self.right_btn = QtWidgets.QPushButton(self.centralwidget)
+ self.right_btn.setGeometry(QtCore.QRect(170, 90, 61, 23))
+ self.right_btn.setObjectName("right_btn")
+ self.speed_lineEdit = QtWidgets.QLineEdit(self.centralwidget)
+ self.speed_lineEdit.setGeometry(QtCore.QRect(101, 10, 131, 20))
+ self.speed_lineEdit.setObjectName("speed_lineEdit")
+ self.speed_ScrollBar = QtWidgets.QScrollBar(self.centralwidget)
+ self.speed_ScrollBar.setGeometry(QtCore.QRect(100, 40, 131, 20))
+ self.speed_ScrollBar.setOrientation(QtCore.Qt.Horizontal)
+ self.speed_ScrollBar.setObjectName("speed_ScrollBar")
+ arcus_ui.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(arcus_ui)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 354, 23))
+ self.menubar.setObjectName("menubar")
+ arcus_ui.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(arcus_ui)
+ self.statusbar.setObjectName("statusbar")
+ arcus_ui.setStatusBar(self.statusbar)
+
+ self.retranslateUi(arcus_ui)
+ QtCore.QMetaObject.connectSlotsByName(arcus_ui)
+
+ def retranslateUi(self, arcus_ui):
+ _translate = QtCore.QCoreApplication.translate
+ arcus_ui.setWindowTitle(_translate("arcus_ui", "MainWindow"))
+ self.left_btn.setText(_translate("arcus_ui", "左"))
+ self.right_btn.setText(_translate("arcus_ui", "右"))
diff --git a/record_system_v24/ui/arcus_control_ui.ui b/record_system_v24/ui/arcus_control_ui.ui
new file mode 100644
index 0000000..b494281
--- /dev/null
+++ b/record_system_v24/ui/arcus_control_ui.ui
@@ -0,0 +1,81 @@
+
+
+ arcus_ui
+
+
+
+ 0
+ 0
+ 354
+ 171
+
+
+
+ MainWindow
+
+
+
+
+
+ 100
+ 90
+ 61
+ 21
+
+
+
+ 左
+
+
+
+
+
+ 170
+ 90
+ 61
+ 23
+
+
+
+ 右
+
+
+
+
+
+ 101
+ 10
+ 131
+ 20
+
+
+
+
+
+
+ 100
+ 40
+ 131
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v24/ui/enter_window.py b/record_system_v24/ui/enter_window.py
new file mode 100644
index 0000000..9f5f1cd
--- /dev/null
+++ b/record_system_v24/ui/enter_window.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'enter_window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_enter_Window(object):
+ def setupUi(self, enter_Window):
+ enter_Window.setObjectName("enter_Window")
+ enter_Window.resize(651, 474)
+ self.centralwidget = QtWidgets.QWidget(enter_Window)
+ self.centralwidget.setObjectName("centralwidget")
+ self.image_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.image_mode_bt.setGeometry(QtCore.QRect(200, 180, 111, 51))
+ self.image_mode_bt.setObjectName("image_mode_bt")
+ self.spectral_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.spectral_mode_bt.setGeometry(QtCore.QRect(360, 180, 111, 51))
+ self.spectral_mode_bt.setObjectName("spectral_mode_bt")
+ self.camstatus_tb = QtWidgets.QTextBrowser(self.centralwidget)
+ self.camstatus_tb.setGeometry(QtCore.QRect(200, 240, 271, 81))
+ self.camstatus_tb.setObjectName("camstatus_tb")
+ enter_Window.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(enter_Window)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 651, 26))
+ self.menubar.setObjectName("menubar")
+ enter_Window.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(enter_Window)
+ self.statusbar.setObjectName("statusbar")
+ enter_Window.setStatusBar(self.statusbar)
+ self.actionwew_e = QtWidgets.QAction(enter_Window)
+ self.actionwew_e.setObjectName("actionwew_e")
+
+ self.retranslateUi(enter_Window)
+ QtCore.QMetaObject.connectSlotsByName(enter_Window)
+
+ def retranslateUi(self, enter_Window):
+ _translate = QtCore.QCoreApplication.translate
+ enter_Window.setWindowTitle(_translate("enter_Window", "主窗口"))
+ self.image_mode_bt.setText(_translate("enter_Window", "影像模式"))
+ self.spectral_mode_bt.setText(_translate("enter_Window", "光谱模式"))
+ self.actionwew_e.setText(_translate("enter_Window", "wew e"))
diff --git a/record_system_v24/ui/enter_window.ui b/record_system_v24/ui/enter_window.ui
new file mode 100644
index 0000000..4c39418
--- /dev/null
+++ b/record_system_v24/ui/enter_window.ui
@@ -0,0 +1,73 @@
+
+
+ enter_Window
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+
+
+ 200
+ 180
+ 111
+ 51
+
+
+
+ 影像模式
+
+
+
+
+
+ 360
+ 180
+ 111
+ 51
+
+
+
+ 光谱模式
+
+
+
+
+
+ 200
+ 240
+ 271
+ 81
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v24/ui/image_Window.py b/record_system_v24/ui/image_Window.py
new file mode 100644
index 0000000..2d176f5
--- /dev/null
+++ b/record_system_v24/ui/image_Window.py
@@ -0,0 +1,246 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window(object):
+ def setupUi(self, image_Window):
+ image_Window.setObjectName("image_Window")
+ image_Window.setEnabled(True)
+ image_Window.resize(1181, 683)
+ image_Window.setMouseTracking(False)
+ image_Window.setAutoFillBackground(False)
+ image_Window.setSizeGripEnabled(False)
+ image_Window.setModal(False)
+ self.gridLayout = QtWidgets.QGridLayout(image_Window)
+ self.gridLayout.setObjectName("gridLayout")
+ self.groupBox_5 = QtWidgets.QGroupBox(image_Window)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
+ self.groupBox_5.setSizePolicy(sizePolicy)
+ self.groupBox_5.setObjectName("groupBox_5")
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.groupBox_5)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ spacerItem = QtWidgets.QSpacerItem(374, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem)
+ self.splitter_2 = QtWidgets.QSplitter(self.groupBox_5)
+ self.splitter_2.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter_2.setObjectName("splitter_2")
+ self.layoutWidget = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(self.layoutWidget)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.label_4 = QtWidgets.QLabel(self.layoutWidget)
+ self.label_4.setObjectName("label_4")
+ self.verticalLayout.addWidget(self.label_4)
+ self.layoutWidget1 = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget1.setObjectName("layoutWidget1")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget1)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.filepath_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filepath_le.setObjectName("filepath_le")
+ self.verticalLayout_2.addWidget(self.filepath_le)
+ self.filename_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filename_le.setObjectName("filename_le")
+ self.verticalLayout_2.addWidget(self.filename_le)
+ self.layoutWidget2 = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget2.setObjectName("layoutWidget2")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.layoutWidget2)
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.filepath_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.verticalLayout_3.addWidget(self.filepath_bt)
+ self.save_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout_3.addWidget(self.save_bt)
+ self.layoutWidget3 = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget3.setObjectName("layoutWidget3")
+ self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.layoutWidget3)
+ self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_7.setObjectName("verticalLayout_7")
+ self.t_label = QtWidgets.QLabel(self.layoutWidget3)
+ self.t_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.t_label.setObjectName("t_label")
+ self.verticalLayout_7.addWidget(self.t_label)
+ self.hum_label = QtWidgets.QLabel(self.layoutWidget3)
+ self.hum_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.verticalLayout_7.addWidget(self.hum_label)
+ self.horizontalLayout_4.addWidget(self.splitter_2)
+ spacerItem1 = QtWidgets.QSpacerItem(374, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem1)
+ self.gridLayout.addWidget(self.groupBox_5, 0, 0, 1, 1)
+ self.splitter = QtWidgets.QSplitter(image_Window)
+ self.splitter.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter.setObjectName("splitter")
+ self.groupBox_3 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth())
+ self.groupBox_3.setSizePolicy(sizePolicy)
+ self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0))
+ self.groupBox_3.setMaximumSize(QtCore.QSize(2000, 16777215))
+ self.groupBox_3.setObjectName("groupBox_3")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_3)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.groupBox = QtWidgets.QGroupBox(self.groupBox_3)
+ self.groupBox.setObjectName("groupBox")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.horizontalLayout.addLayout(self.image_glo)
+ self.verticalLayout_4.addWidget(self.groupBox)
+ self.statu_tb = QtWidgets.QTextBrowser(self.groupBox_3)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.statu_tb.sizePolicy().hasHeightForWidth())
+ self.statu_tb.setSizePolicy(sizePolicy)
+ self.statu_tb.setMaximumSize(QtCore.QSize(8777215, 100))
+ self.statu_tb.setReadOnly(True)
+ self.statu_tb.setObjectName("statu_tb")
+ self.verticalLayout_4.addWidget(self.statu_tb)
+ self.groupBox_4 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_4.sizePolicy().hasHeightForWidth())
+ self.groupBox_4.setSizePolicy(sizePolicy)
+ self.groupBox_4.setObjectName("groupBox_4")
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_4)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox_4)
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_2)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.horizontalLayout_2.addLayout(self.focus_glo)
+ self.verticalLayout_5.addWidget(self.groupBox_2)
+ self.groupBox_6 = QtWidgets.QGroupBox(self.groupBox_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_6.sizePolicy().hasHeightForWidth())
+ self.groupBox_6.setSizePolicy(sizePolicy)
+ self.groupBox_6.setObjectName("groupBox_6")
+ self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.groupBox_6)
+ self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+ self.groupBox_7 = QtWidgets.QGroupBox(self.groupBox_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
+ self.groupBox_7.setSizePolicy(sizePolicy)
+ self.groupBox_7.setMaximumSize(QtCore.QSize(500, 500))
+ self.groupBox_7.setObjectName("groupBox_7")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.verticalLayout_6 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_6.setObjectName("verticalLayout_6")
+ self.label_3 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout_6.addWidget(self.label_3)
+ self.image_mode_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_focus_bt.setObjectName("image_mode_focus_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_focus_bt)
+ self.image_mode_exposureTime_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_exposureTime_bt.setObjectName("image_mode_exposureTime_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_exposureTime_bt)
+ self.label_5 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_5.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_5.setObjectName("label_5")
+ self.verticalLayout_6.addWidget(self.label_5)
+ self.image_mode_wb_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_wb_bt.setObjectName("image_mode_wb_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_wb_bt)
+ self.label_2 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout_6.addWidget(self.label_2)
+ self.image_mode_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_record_bt.setObjectName("image_mode_record_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_6)
+ self.verticalLayout_8 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_8.setObjectName("verticalLayout_8")
+ self.framerate_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.verticalLayout_8.addWidget(self.framerate_le)
+ self.image_mode_stop_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_stop_focus_bt.setObjectName("image_mode_stop_focus_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_stop_focus_bt)
+ self.exposureTime_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.exposureTime_le.setObjectName("exposureTime_le")
+ self.verticalLayout_8.addWidget(self.exposureTime_le)
+ self.gain_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.gain_le.setObjectName("gain_le")
+ self.verticalLayout_8.addWidget(self.gain_le)
+ self.image_mode_dc_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_dc_bt.setObjectName("image_mode_dc_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_dc_bt)
+ self.framenumber_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.verticalLayout_8.addWidget(self.framenumber_le)
+ self.image_mode_motor_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_motor_bt.setObjectName("image_mode_motor_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_motor_bt)
+ self.image_mode_stop_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_stop_record_bt.setObjectName("image_mode_stop_record_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_stop_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_8)
+ self.horizontalLayout_5.addWidget(self.groupBox_7)
+ spacerItem2 = QtWidgets.QSpacerItem(261, 17, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_5.addItem(spacerItem2)
+ self.verticalLayout_5.addWidget(self.groupBox_6)
+ self.gridLayout.addWidget(self.splitter, 1, 0, 1, 1)
+
+ self.retranslateUi(image_Window)
+ QtCore.QMetaObject.connectSlotsByName(image_Window)
+
+ def retranslateUi(self, image_Window):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window.setWindowTitle(_translate("image_Window", "影像窗口"))
+ self.groupBox_5.setTitle(_translate("image_Window", "GroupBox"))
+ self.label.setText(_translate("image_Window", "保存路径"))
+ self.label_4.setText(_translate("image_Window", "文件名"))
+ self.filepath_bt.setText(_translate("image_Window", "浏览"))
+ self.save_bt.setText(_translate("image_Window", "保存"))
+ self.t_label.setText(_translate("image_Window", "温度:无数据"))
+ self.hum_label.setText(_translate("image_Window", "湿度:无数据"))
+ self.groupBox_3.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox.setTitle(_translate("image_Window", "图像"))
+ self.groupBox_4.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_2.setTitle(_translate("image_Window", "光谱"))
+ self.groupBox_6.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_7.setTitle(_translate("image_Window", "GroupBox"))
+ self.label_3.setText(_translate("image_Window", "帧率"))
+ self.image_mode_focus_bt.setText(_translate("image_Window", "调焦"))
+ self.image_mode_exposureTime_bt.setText(_translate("image_Window", "曝光"))
+ self.label_5.setText(_translate("image_Window", "gain"))
+ self.image_mode_wb_bt.setText(_translate("image_Window", "白板"))
+ self.label_2.setText(_translate("image_Window", "帧数"))
+ self.image_mode_record_bt.setText(_translate("image_Window", "采集"))
+ self.image_mode_stop_focus_bt.setText(_translate("image_Window", "停止调焦"))
+ self.image_mode_dc_bt.setText(_translate("image_Window", "暗电流"))
+ self.image_mode_motor_bt.setText(_translate("image_Window", "马达"))
+ self.image_mode_stop_record_bt.setText(_translate("image_Window", "停止采集"))
diff --git a/record_system_v24/ui/image_Window.ui b/record_system_v24/ui/image_Window.ui
new file mode 100644
index 0000000..588fe4c
--- /dev/null
+++ b/record_system_v24/ui/image_Window.ui
@@ -0,0 +1,405 @@
+
+
+ image_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 1179
+ 683
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 湿度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 374
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
-
+
+
+ 保存路径
+
+
+
+ -
+
+
+ 文件名
+
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ 浏览
+
+
+
+ -
+
+
+ 保存
+
+
+
+
+
+
+
+ -
+
+
+ 温度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 374
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 2000
+ 16777215
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 图像
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 8777215
+ 100
+
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+ -
+
+
+ 光谱
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 500
+ 500
+
+
+
+ GroupBox
+
+
+
-
+
+
-
+
+
+ 帧率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 调焦
+
+
+
+ -
+
+
+ 曝光
+
+
+
+ -
+
+
+ gain
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 白板
+
+
+
+ -
+
+
+ 帧数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ -
+
+
+ 停止调焦
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ -
+
+
+ 马达
+
+
+
+ -
+
+
+ 停止采集
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 261
+ 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v24/ui/spectral_Window.py b/record_system_v24/ui/spectral_Window.py
new file mode 100644
index 0000000..6e89899
--- /dev/null
+++ b/record_system_v24/ui/spectral_Window.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window(object):
+ def setupUi(self, spectral_Window):
+ spectral_Window.setObjectName("spectral_Window")
+ spectral_Window.resize(820, 545)
+ self.label = QtWidgets.QLabel(spectral_Window)
+ self.label.setGeometry(QtCore.QRect(54, 10, 51, 20))
+ self.label.setObjectName("label")
+ self.filepath_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filepath_le.setGeometry(QtCore.QRect(131, 10, 261, 21))
+ self.filepath_le.setObjectName("filepath_le")
+ self.label_2 = QtWidgets.QLabel(spectral_Window)
+ self.label_2.setGeometry(QtCore.QRect(54, 40, 41, 20))
+ self.label_2.setObjectName("label_2")
+ self.filename_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filename_le.setGeometry(QtCore.QRect(131, 40, 261, 21))
+ self.filename_le.setObjectName("filename_le")
+ self.filepath_bt = QtWidgets.QPushButton(spectral_Window)
+ self.filepath_bt.setGeometry(QtCore.QRect(401, 10, 71, 21))
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.statu_tb = QtWidgets.QTextBrowser(spectral_Window)
+ self.statu_tb.setGeometry(QtCore.QRect(620, 240, 161, 301))
+ self.statu_tb.setObjectName("statu_tb")
+ self.tabWidget = QtWidgets.QTabWidget(spectral_Window)
+ self.tabWidget.setGeometry(QtCore.QRect(10, 70, 591, 441))
+ self.tabWidget.setObjectName("tabWidget")
+ self.tab = QtWidgets.QWidget()
+ self.tab.setObjectName("tab")
+ self.gridLayoutWidget = QtWidgets.QWidget(self.tab)
+ self.gridLayoutWidget.setGeometry(QtCore.QRect(0, 0, 581, 411))
+ self.gridLayoutWidget.setObjectName("gridLayoutWidget")
+ self.spe_glo = QtWidgets.QGridLayout(self.gridLayoutWidget)
+ self.spe_glo.setContentsMargins(0, 0, 0, 0)
+ self.spe_glo.setObjectName("spe_glo")
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_2 = QtWidgets.QWidget()
+ self.tab_2.setObjectName("tab_2")
+ self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab_2)
+ self.gridLayoutWidget_2.setGeometry(QtCore.QRect(-1, -1, 581, 411))
+ self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
+ self.align_glo = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
+ self.align_glo.setContentsMargins(0, 0, 0, 0)
+ self.align_glo.setObjectName("align_glo")
+ self.tabWidget.addTab(self.tab_2, "")
+ self.layoutWidget = QtWidgets.QWidget(spectral_Window)
+ self.layoutWidget.setGeometry(QtCore.QRect(610, 90, 195, 135))
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.spectral_mode_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_align_bt.setObjectName("spectral_mode_align_bt")
+ self.gridLayout.addWidget(self.spectral_mode_align_bt, 0, 0, 1, 1)
+ self.spectral_mode_stop_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_stop_align_bt.setObjectName("spectral_mode_stop_align_bt")
+ self.gridLayout.addWidget(self.spectral_mode_stop_align_bt, 0, 1, 1, 1)
+ self.spectral_mode_wb_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_wb_bt.setObjectName("spectral_mode_wb_bt")
+ self.gridLayout.addWidget(self.spectral_mode_wb_bt, 1, 0, 1, 2)
+ self.spectral_mode_dc_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_dc_bt.setObjectName("spectral_mode_dc_bt")
+ self.gridLayout.addWidget(self.spectral_mode_dc_bt, 2, 0, 1, 2)
+ self.spectral_mode_record_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_record_bt.setObjectName("spectral_mode_record_bt")
+ self.gridLayout.addWidget(self.spectral_mode_record_bt, 3, 0, 1, 2)
+ self.t_label = QtWidgets.QLabel(spectral_Window)
+ self.t_label.setGeometry(QtCore.QRect(490, 11, 78, 23))
+ self.t_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.t_label.setObjectName("t_label")
+ self.hum_label = QtWidgets.QLabel(spectral_Window)
+ self.hum_label.setGeometry(QtCore.QRect(490, 40, 78, 23))
+ self.hum_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.hum_label.setObjectName("hum_label")
+
+ self.retranslateUi(spectral_Window)
+ self.tabWidget.setCurrentIndex(0)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window)
+
+ def retranslateUi(self, spectral_Window):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window.setWindowTitle(_translate("spectral_Window", "光谱窗口"))
+ self.label.setText(_translate("spectral_Window", "保存路径"))
+ self.label_2.setText(_translate("spectral_Window", "文件名"))
+ self.filepath_bt.setText(_translate("spectral_Window", "浏览"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("spectral_Window", "spe"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("spectral_Window", "align"))
+ self.spectral_mode_align_bt.setText(_translate("spectral_Window", "align"))
+ self.spectral_mode_stop_align_bt.setText(_translate("spectral_Window", "stop align"))
+ self.spectral_mode_wb_bt.setText(_translate("spectral_Window", "曝光/白板"))
+ self.spectral_mode_dc_bt.setText(_translate("spectral_Window", "暗电流"))
+ self.spectral_mode_record_bt.setText(_translate("spectral_Window", "采集"))
+ self.t_label.setText(_translate("spectral_Window", "温度:无数据"))
+ self.hum_label.setText(_translate("spectral_Window", "湿度:无数据"))
diff --git a/record_system_v24/ui/spectral_Window.ui b/record_system_v24/ui/spectral_Window.ui
new file mode 100644
index 0000000..4d1c99d
--- /dev/null
+++ b/record_system_v24/ui/spectral_Window.ui
@@ -0,0 +1,212 @@
+
+
+ spectral_Window
+
+
+
+ 0
+ 0
+ 820
+ 545
+
+
+
+ 光谱窗口
+
+
+
+
+ 54
+ 10
+ 51
+ 20
+
+
+
+ 保存路径
+
+
+
+
+
+ 131
+ 10
+ 261
+ 21
+
+
+
+
+
+
+ 54
+ 40
+ 41
+ 20
+
+
+
+ 文件名
+
+
+
+
+
+ 131
+ 40
+ 261
+ 21
+
+
+
+
+
+
+ 401
+ 10
+ 71
+ 21
+
+
+
+ 浏览
+
+
+
+
+
+ 620
+ 240
+ 161
+ 301
+
+
+
+
+
+
+ 10
+ 70
+ 591
+ 441
+
+
+
+ 0
+
+
+
+ spe
+
+
+
+
+ 0
+ 0
+ 581
+ 411
+
+
+
+
+
+
+
+ align
+
+
+
+
+ -1
+ -1
+ 581
+ 411
+
+
+
+
+
+
+
+
+
+ 610
+ 90
+ 195
+ 135
+
+
+
+ -
+
+
+ align
+
+
+
+ -
+
+
+ stop align
+
+
+
+ -
+
+
+ 曝光/白板
+
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+
+
+
+ 490
+ 11
+ 78
+ 23
+
+
+
+ 温度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 490
+ 40
+ 78
+ 23
+
+
+
+ 湿度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
diff --git a/record_system_v25/2record_system_v25.py b/record_system_v25/2record_system_v25.py
new file mode 100644
index 0000000..1808790
--- /dev/null
+++ b/record_system_v25/2record_system_v25.py
@@ -0,0 +1,1801 @@
+# -*- coding:utf-8 -*-
+
+'''
+在2record system_v2.2的基础上更新:
+1、优化了图像显示和光谱显示:使用QGraphicsView显示图像
+2、通过包组织代码,降低主程序的复杂度
+3、
+4、
+5、
+6、
+7、
+'''
+
+# 内置包
+import os, sys, functools, re, shutil, traceback, time
+import subprocess
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+import logging
+
+# 三方包
+import numpy as np
+from osgeo import gdal
+from ximea import xiapi
+import configparser
+import serial
+import serial.tools.list_ports
+from serial.serialutil import SerialBase, SerialException
+
+# 界面包
+import qimage2ndarray
+from PyQt5.QtCore import Qt, QObject, QThreadPool, QTimer, QRegExp
+# from PyQt5.QtCore import QRectF, pyqtSignal, QRunnable, pyqtSlot, QT_VERSION_STR
+from PyQt5.QtGui import QIntValidator, QRegExpValidator, QPixmap, QImage, QPainterPath
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
+
+from QtImageViewer import QtImageViewer
+from QtSpectralViewer import QtSpectralViewer
+from library.multithread import Worker, WorkerSignals
+from library.image_reader_writer import ImageReaderWriter
+from library.functions import get_path, get_resource_path, return_file_path
+
+from record_system_v25.ui.enter_window import *
+from record_system_v25.ui.image_Window import *
+from record_system_v25.ui.spectral_Window import *
+from record_system_v25.ui.arcus_control_ui import *
+
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from library.matplotlib_display_image_spectral import MatplotlibSpectralViewer, MatplotlibImageViewer
+
+
+class ArcusWindow(QMainWindow, Ui_arcus_ui):
+ def __init__(self, parent=None):
+ super(ArcusWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ self.left_btn.pressed.connect(self.leftMove)
+ self.left_btn.released.connect(self.stop)
+ self.right_btn.pressed.connect(self.rightMove)
+ self.right_btn.released.connect(self.stop)
+
+ # self.speed_lineEdit.setText(self.arc.write('HSPD'))
+ self.speed_lineEdit.textEdited.connect(self.change_speed)
+
+ self.time = time.time() # 控制两次点击后,发送命令的间隔
+
+ def leftMove(self):
+ time_now = time.time()
+ if time_now - self.time > 0:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J-'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' CLR EO=1 J-'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('左移ok!')
+
+ def rightMove(self):
+ time_now = time.time()
+ if time_now - self.time > 0.5:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J+'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' CLR EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ print(output)
+ # print(error)
+ print('右移ok!')
+
+ def change_speed(self):
+ time_now = time.time()
+ if time_now - self.time > 0.5:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py HSPD=' + str(self.speed_lineEdit.text())
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' HSPD=' + str(self.speed_lineEdit.text())
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('改变速度ok!')
+
+ def stop(self):
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py STOP'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' STOP'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('停止ok!')
+
+
+# 主窗口
+class EnterWindow(QMainWindow, Ui_enter_Window):
+ def __init__(self, parent=None):
+ super(EnterWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ # 在刚打开软件在本窗口显示相机状态(是否打开)
+ self.c = WorkerSignals()
+ self.c.openinfo.connect(self.printCamInfo)
+ self.c.openinfo.emit(2)
+
+ # self.spectral_mode_bt.clicked.connect(self.spectral_window)
+ self.image_window_instance = ImageWindow()
+ self.image_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.image_mode_bt.clicked.connect(self.image_window_instance.show)
+
+ self.spectral_window_instance = SpectralWindow()
+ self.spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.spectral_mode_bt.clicked.connect(self.spectral_window_instance.show)
+
+ def printCamInfo(self, cam_status):
+ '''
+ :param cam_status: 0代表相机打开出错;1代表相机打开成功;2代表正在打开相机
+ :return:
+ '''
+ if cam_status == 1:
+ self.camstatus_tb.append('相机打开成功!')
+
+ self.image_mode_bt.setDisabled(False)
+ self.spectral_mode_bt.setDisabled(False)
+ elif cam_status == 0:
+ self.camstatus_tb.append('相机打开失败!')
+
+ self.image_mode_bt.setDisabled(True)
+ self.spectral_mode_bt.setDisabled(True)
+ elif cam_status == 2:
+ self.camstatus_tb.append('正在打开相机...')
+
+ self.image_mode_bt.setDisabled(True)
+ self.spectral_mode_bt.setDisabled(True)
+
+
+class SerialPort(QObject):
+ def __init__(self):
+ super(SerialPort, self).__init__()
+
+ self.logger = logging.getLogger('root.serial')
+
+ formatter1 = logging.Formatter('%(asctime)s %(message)s')
+ temperature_file_handler = logging.FileHandler(system_setting.log_dir + '//temperature.log') # 输出到文件
+ temperature_file_handler.setLevel(logging.DEBUG)
+ temperature_file_handler.setFormatter(formatter1)
+
+ self.logger.addHandler(temperature_file_handler)
+
+
+
+ # self.signals = pyqtSignal(tuple) # 为啥这就不行呢?
+ self.signals = WorkerSignals()
+
+ self.connect_number = 0 # 记录打开串口的次数
+ self.serial_port = self.open_serial_port()
+
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.receiver_data_from_port)
+ self.timer.start(1000)
+
+ def open_serial_port(self):
+ self.connect_number += 1
+ port_list = list(serial.tools.list_ports.comports()) # 列出所有可用串口
+ # print(port_list)
+
+ if len(port_list) > 0: # 如果可用串口 >0 个
+ # 打印出所有串口的信息
+ for i in range(0, len(port_list)):
+ print(port_list[i])
+
+ # 打开第一个串口
+ ser = serial.Serial(port_list[0].device)
+ # print('温湿度传感器打开成功!')
+ return ser
+ elif len(port_list) == 0: # 如果可用串口为0个
+ if self.connect_number == 1:
+ self.logger.info('无可用串口,温湿度传感器不可用!')
+ else:
+ self.logger.error('串口连接上之后,断开连接!')
+ return 1 # 如果返回1,则代表没有可用串口;通过1来判断不执行定时器触发:self.timer.start(1000)
+ else: # 其他没有考虑到的情况
+ return 1
+
+ def receiver_data_from_port(self):
+ '''
+ 定时器QTimer没隔1s调用此函数一次 → 让串口buffer有足够的数据等待读取
+ :return: 无返回值
+
+ 本函数功能:1、串口中接收字节数据,有两种帧 → 代表两种数据
+ 2、判断帧头位置和本帧数据类型
+ 3、判断帧尾 → 等效判断本帧数据是否完全
+ 4、如果数据帧完整 → 解析数据,将温度湿度显示到界面上和写入到文件中
+ '''
+ try:
+ if self.serial_port.in_waiting: # 如果串口buffer有数据等待读取
+ bytes_receive = self.serial_port.read(self.serial_port.inWaiting()) # 读取串口buffer的数据
+ # print(len(bytes_receive))
+
+ # 判断帧头位置,通过正则表达式
+ hex_receive = bytes_receive.hex() # 一个字节需要一个两位16进制数表示,所以:len(hex_receive) = len(bytes_receive) * 2
+ p = re.compile('5a5a*')
+ index_head = [i.start() / 2 for i in re.finditer(p, hex_receive)] # re.finditer()
+ # print(hex_receive)
+ # print(index_head)
+ except SerialException: # 程序打开时,温湿度传感器的串口工作正常;如果程序运行中拔掉串口就会出现此异常
+ self.logger.error('在程序运行中温湿度传感器的串口出现问题!')
+
+ # 再次尝试打开串口
+ self.serial_port = self.open_serial_port()
+ if not isinstance(self.serial_port, int):
+ self.logger.info('再次尝试连接温湿度传感器成功!')
+ else:
+ self.logger.info('再次尝试连接温湿度传感器失败!')
+ except AttributeError: # int object has no attribute: in_waiting
+ self.timer.stop()
+ self.logger.info('停止定时触发器!')
+ except Exception as e: # 未出现过的异常。当第一次出现时,需要编写代码处理,先写入日志文件(log)
+ self.logger.critical('未知错误!')
+ else: # 当没有捕获到异常时,代表串口数据获取成功 → 执行数据解析
+ # 解析数据
+ try:
+ if len(index_head) != 0:
+ Lux = 1.0
+ T = 1.0
+ P = 1.0
+ Hum = 1.0
+ H = 1.0
+ Lux_full = 0 # 判断光照帧的数据是否完整。0:不完整;1:完整;
+ T_full = 0 # 判断温度帧的数据是否完整。0:不完整;1:完整;
+ try:
+ for i in index_head: # 循环遍历每个帧头
+ if bytes_receive[int(i) + 2] == 21: # 0x15=21,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 8]) & 0xff == bytes_receive[int(i) + 8]: # 判断帧尾是否正确
+ # print('光照帧的帧尾正确!')
+
+ Lux_full = 1 # 如果帧尾,此帧数据数完整的
+ Lux = ((bytes_receive[int(i) + 4] << 24) | (bytes_receive[int(i) + 5] << 16) | (
+ bytes_receive[int(i) + 6] << 8) | bytes_receive[int(i) + 7]) / 100
+ if bytes_receive[int(i) + 2] == 69: # 0x45=69,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 14]) & 0xff == bytes_receive[int(i) + 14]: # 判断帧尾是否正确
+ # print('温度帧的帧尾正确!')
+
+ T_full = 1 # 当执行这段代码时,代表帧头帧尾都正常,此帧数据数完整的
+ T = ((bytes_receive[int(i) + 4] << 8) | bytes_receive[int(i) + 5]) / 100
+ P = ((bytes_receive[int(i) + 6] << 24) | (bytes_receive[int(i) + 7] << 16) | (
+ bytes_receive[int(i) + 8] << 8) | bytes_receive[
+ int(i) + 9]) / 100
+ Hum = ((bytes_receive[int(i) + 10] << 8) | bytes_receive[int(i) + 11]) / 100
+ H = ((bytes_receive[int(i) + 12] << 8) | bytes_receive[int(i) + 13]) / 100
+ except IndexError as e: # 当出现帧头,但是帧头到帧尾的数据不全 → 在判断帧尾是否正确时就会出现索引越界
+ # print('----------------------索引越界!')
+ pass
+ except Exception: # 当出现前面没有解决的异常时,前面的异常捕捉就失效。最后通过异常基类来捕捉 → 代表需要修改代码进行处理的新异常
+ # print('---------------------------------没遇见过的异常')
+ pass
+
+ # 将数据显示和写入文件
+ if Lux_full + T_full == 2: # x + y == 2代表温度帧和光照帧都完整
+ # self.t_label.setVisible(True)
+ # self.hum_label.setVisible(True)
+ # self.t_label.setText('温度:' + str(T))
+ # self.hum_label.setText('湿度:' + str(Hum))
+
+ # print('发送数据')
+
+ self.signals.serial.emit((str(T), str(Hum)))
+ self.logger.debug('%s %s', str(T), str(Hum))
+
+ # print('光照强度:%f' % Lux)
+ # print('温度:%f' % T)
+ # print('气压:%f' % P)
+ # print('湿度:%f' % Hum)
+ # print('海拔:%f' % H)
+ # print()
+ elif Lux_full + T_full == 1:
+ # print('只有一个数据帧是完整的。(光照帧或者温度帧)')
+ # print()
+ pass
+ except UnboundLocalError:
+ # print(2222222222222222222222222222222)
+ # traceback.print_exc()
+ pass
+ except Exception:
+ self.logger.critical('未知错误!')
+ finally: # 不管有没有捕获到异常都会执行,一般用作资源回收
+ pass
+
+
+# 图像窗口
+class ImageWindow(QDialog, Ui_image_Window):
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(ImageWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+
+ self.arcus_window_instance = ArcusWindow()
+ self.image_mode_motor_bt.clicked.connect(self.arcus_window_instance.show)
+
+ # log
+ self.logger = logging.getLogger('root.image')
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ image_operate_file_handler = logging.FileHandler(system_setting.log_dir + "//image_operate.log") # 输出到文件
+ image_operate_file_handler.setLevel(logging.INFO)
+ image_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(image_operate_file_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.signals.serial.connect(self.temperature)
+
+ # 采集影像时,边采集边刷新显示
+ # self.plotsignal = pyqtSignal() # 直接这样建立信号执行时会报错
+ self.plotsignal = WorkerSignals()
+ self.plotsignal.plotsignal.connect(self.plotimg)
+
+ #建立进程池
+ # https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ #初始化窗口中的值
+ self.framenumber_le.setText(str(system_setting.frame_number))
+ CameraOperation.framenumber_input = system_setting.frame_number
+ CameraOperation.rgb = np.ones((3, int(system_setting.frame_number), int(
+ (CameraOperation.endColumn - CameraOperation.startColumn) / CameraOperation.bin_spatial)))
+ self.framerate_le.setText(str(system_setting.framerate))
+ self.exposure_time_le.setText(str(system_setting.exposure_time))
+ self.gain_le.setText(str(system_setting.gain))
+ self.filename_le.setText(system_setting.default_image_name)
+ self.filepath_le.setText(system_setting.image_dir)
+
+ # self.framenumber_le.setText(str(CameraOperation.framenumber_input))
+ # self.framerate_le.setText(str(CameraOperation.framerate_input))
+ # self.exposure_time_le.setText(str(CameraOperation.exposureTime_input))
+ # self.gain_le.setText(str(CameraOperation.gain_input))
+ # self.filename_le.setText(system_setting.default_image_name)
+ # self.filepath_le.setText(system_setting.image_dir)
+
+ # #手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ # self.exposure_time_le.textEdited.connect(self.onchange2)
+ # self.exposure_time_le.textChanged.connect(self.onchange)# 将 自动曝光返回到QLineEdit中的值 写入到camera_operation.exposureTime_input
+ # self.gain_le.textEdited.connect(self.onchange2)
+ # self.gain_le.textChanged.connect(self.onchange)# 将 自动曝光返回到QLineEdit中的值 写入到camera_operation.gain_input
+ # self.framerate_le.textEdited.connect(self.onchange2)
+ # self.framenumber_le.textEdited.connect(self.onchange)
+ # self.filename_le.textEdited.connect(self.onchange)
+ # self.filepath_bt.clicked.connect(self.directory_select)
+ # self.filepath_le.textEdited.connect(self.onchange)
+
+ # 显示影像和调焦
+ # self.myImageFigure = MatplotlibImageViewer()
+ self.myImageFigure = QtImageViewer()
+ self.myImageFigure.leftMouseButtonPressed.connect(self.handleLeftClick)
+ self.image_glo.addWidget(self.myImageFigure)
+
+ self.myFocusFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)')
+ # self.myFocusFigure = QtSpectralViewer(xlabel='Wavelength (nm)')
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ #操作光谱仪
+ ## 注释的代码没有使用多线程,所以会造成一采集数据界面就卡死的情况
+ # self.focus_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.dc_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.save_bt.clicked.connect(camera_operation.savedata)
+ self.image_mode_exposureTime_bt.clicked.connect(self.run)
+ self.image_mode_focus_bt.clicked.connect(self.run)
+ # 停止调焦和采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_mode_stop_focus_bt.clicked.connect(self.stop_focus)
+ self.image_mode_stop_record_bt.clicked.connect(self.stop_record)
+ self.image_mode_dc_bt.clicked.connect(self.run)
+ self.image_mode_wb_bt.clicked.connect(self.run)
+ self.image_mode_record_bt.clicked.connect(self.run)
+ self.save_bt.clicked.connect(self.save_image)
+
+ # 手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.exposure_time_le.setValidator(QIntValidator()) # QIntValidator是一个类
+ self.gain_le.setValidator(QIntValidator())
+ self.framerate_le.setValidator(QIntValidator())
+ self.framenumber_le.setValidator(QIntValidator())
+
+ my_regex = QRegExp("[a-zA-Z0-9]*")
+ my_validator = QRegExpValidator(my_regex, self.filename_le)
+ self.filename_le.setValidator(my_validator)
+
+ self.exposure_time_le.editingFinished.connect(self.text_edited)
+ # self.exposure_time_le.setPlaceholderText('曝光时间')
+ self.gain_le.editingFinished.connect(self.text_edited)
+ self.framerate_le.editingFinished.connect(self.text_edited)
+ self.framenumber_le.editingFinished.connect(self.text_edited)
+ self.filename_le.editingFinished.connect(self.text_edited)
+ self.filepath_le.editingFinished.connect(self.text_edited)
+
+ self.filepath_bt.clicked.connect(self.directory_select)
+
+ self.cwd = system_setting.image_dir
+
+ def handleLeftClick(self, x, y):
+ # 画出光谱
+ try:
+ # 计算波长
+ def calculate_wavelength(x):
+ wavelength = x * 1.999564 - 279.893
+ return wavelength
+
+ wavelength = np.empty(639 - 339)
+ for i in range(339, 639):
+ wavelength[i - 339] = calculate_wavelength(i)
+
+ row = int(y)
+ column = int(x)
+ # print("Pixel (row=" + str(row) + ", column=" + str(column) + ")")
+
+ _, _, img = ImageReaderWriter.read_img('corning410_test', column, row, 1, 1)
+
+ if isinstance(img, np.ndarray): # 如果点击到图像之外,img就是NoneType,就不重画光谱
+ # print('点击有效')
+
+ self.myFocusFigure.plot_wrap(wavelength, img[:, 0, 0])
+ except TypeError:
+ pass
+ # print('有错')
+ # self.logger.critical('TypeError:', exc_info=True)
+ except Exception:
+ self.logger.critical('点击显示光谱时出现未知错误:', exc_info=True)
+ traceback.print_exc()
+
+ # 手动修改界面中的值后,为相机重新设置如下参数:exposure, gain, framerate
+ def text_edited(self):
+ try:
+ system_setting.exposure_time = int(self.exposure_time_le.text())
+ system_setting.gain = int(float(self.gain_le.text()))
+ system_setting.framerate = int(self.framerate_le.text())
+ system_setting.frame_number = int(self.framenumber_le.text())
+ system_setting.default_image_name = self.filename_le.text()
+
+ system_setting.signals.image_signal.emit(
+ {'exposure_time': int(self.exposure_time_le.text()), 'gain': int(float(self.gain_le.text())),
+ 'framerate': int(self.framerate_le.text()), 'frame_number': int(self.framenumber_le.text()),
+ 'default_image_name': self.filename_le.text()})
+ except ValueError:
+ QMessageBox.information(self, '提示', '请输入正确的值!', QMessageBox.Yes)
+ except Exception:
+ self.logger.critical('设置曝光/gain/帧率/帧数时出现未知错误!', exe_info=True)
+
+ CameraOperation.set_exposure_gain_framerate(camera)
+
+ CameraOperation.fn = system_setting.default_image_name
+
+ CameraOperation.framenumber_input = system_setting.frame_number
+ CameraOperation.rgb = np.ones((3, int(system_setting.frame_number), int(
+ (CameraOperation.endColumn - CameraOperation.startColumn) / CameraOperation.bin_spatial)))
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和system_setting对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ print(result)
+ self.exposure_time_le.setText(str(result[0]))
+ self.gain_le.setText(str(result[1]))
+
+ # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为system_setting.exposure_time的旧值
+ system_setting.exposure_time = result[0]
+ system_setting.gain = result[1]
+
+ try:
+ system_setting.signals.image_signal.emit({'exposure_time': result[0], 'gain': result[1]})
+ except:
+ traceback.print_exc()
+
+ CameraOperation.set_exposure_gain_framerate(camera)
+
+ if result[2] == 1:
+ QMessageBox.information(self, '曝光提示', '光线不足,曝光时间已设置为最大!', QMessageBox.Yes)
+ CameraOperation.autoexposure_feedback = 0
+
+ def temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+ except:
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def timer_start(self):
+ '''
+ 本函数目的是在self.timer.start(1000)外包裹一层(有点装饰器的感觉),加入判断:
+ 1、如果self.serial_port为串口类型,就触发定时器self.timer.start(1000)
+ 2、如果self.serial_port == 1(为int类型),则代表硬件中没有温湿度传感器,就没必要触发定时器self.timer.start(1000)
+ :return: 无返回值
+ '''
+
+ if isinstance(self.serial_port, serial.serialwin32.Serial):
+ self.timer.start(1000)
+ elif isinstance(self.serial_port, int):
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ else:
+ pass
+
+ def plotimg(self):
+ worker = Worker(CameraOperation.plotimg)
+ self.threadpool.start(worker)
+
+ def stop_focus(self):
+ CameraOperation.focus = False
+
+ def stop_record(self):
+ CameraOperation.record = False
+
+ # 调焦、采集暗电流、采集白板、采集影像 都通过此函数
+ def run(self):
+ try:
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.statu_tb.append('自动曝光...')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.statu_tb.append('调焦...')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.statu_tb.append('采集白板...')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.statu_tb.append('采集影像...')
+
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(CameraOperation.start_AcquireData, camera, self.qt_sender)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ self.save_bt.setDisabled(True)
+ self.image_mode_exposureTime_bt.setDisabled(True)
+ self.image_mode_focus_bt.setDisabled(True)
+ self.image_mode_dc_bt.setDisabled(True)
+ self.image_mode_wb_bt.setDisabled(True)
+ self.image_mode_record_bt.setDisabled(True)
+ self.save_bt.setDisabled(True)
+ except Exception:
+ traceback.print_exc()
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.statu_tb.append('自动曝光失败!')
+ self.logger.error('自动曝光失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.statu_tb.append('调焦失败!')
+ self.logger.error('调焦失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.statu_tb.append('采集暗电流失败!')
+ self.logger.error('采集暗电流失败:光谱仪正在工作中,请稍等\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.statu_tb.append('采集白板失败!')
+ self.logger.error('采集白板失败:光谱仪正在工作中,请稍等\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.statu_tb.append('采集影像失败!')
+ self.logger.error('采集影像失败:光谱仪正在工作中,请稍等\n%s', traceback_info[2])
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'save_bt':
+ self.statu_tb.append('保存影像失败!')
+ self.logger.error('保存影像失败!\n%s', traceback_info[2])
+ QMessageBox.information(self, '提示', '请输入正确的影像名!', QMessageBox.Yes)
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.statu_tb.append('自动曝光成功!')
+ self.logger.info('自动曝光成功!')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.statu_tb.append('调焦成功!')
+ self.logger.info('调焦成功!')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.statu_tb.append('采集暗电流成功!')
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.statu_tb.append('采集白板成功!')
+ self.logger.info('采集白板成功!')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.statu_tb.append('采集影像成功!')
+ self.logger.info('采集影像成功!')
+ elif self.qt_sender == 'save_bt':
+ self.statu_tb.append('保存影像成功!')
+ self.logger.info('保存影像成功!')
+
+ self.save_bt.setDisabled(False)
+ self.image_mode_exposureTime_bt.setDisabled(False)
+ self.image_mode_focus_bt.setDisabled(False)
+ self.image_mode_dc_bt.setDisabled(False)
+ self.image_mode_wb_bt.setDisabled(False)
+ self.image_mode_record_bt.setDisabled(False)
+ self.save_bt.setDisabled(False)
+
+ def save_image(self):
+ # 操作状态显示
+ self.qt_sender = self.sender().objectName()
+ self.statu_tb.append('保存影像...')
+
+ worker = Worker(CameraOperation.savedata)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+
+ self.threadpool.start(worker)
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', self.cwd)
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.cwd = dirpath
+
+ self.filepath_le.setText(dirpath)
+ system_setting.signals.image_signal.emit({'image_dir': dirpath})
+
+ self.logger.info('选择影像保存路径!')
+
+
+# 光谱窗口
+class SpectralWindow(QDialog, Ui_spectral_Window):
+ def __init__(self, parent=None):
+ super(SpectralWindow, self).__init__(parent)
+ self.setupUi(self)
+
+ # log
+ self.logger = logging.getLogger('root.spectral')
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.signals.serial.connect(self.temperature)
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ spectral_operate_file_handler = logging.FileHandler(system_setting.log_dir + "//spectral_operate.log") # 输出到文件
+ spectral_operate_file_handler.setLevel(logging.INFO)
+ spectral_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(spectral_operate_file_handler)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化值
+ self.filename_le.setText(system_setting.default_spectral_name)
+ self.filepath_le.setText(system_setting.spectral_dir)
+
+ # 显示光谱和align
+ self.spectralFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
+ # self.spectralFigure = QtSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
+ self.spe_glo.addWidget(self.spectralFigure)
+
+ self.alignFigure = MatplotlibImageViewer()
+ # self.alignFigure = QtImageViewer()
+ self.align_glo.addWidget(self.alignFigure)
+
+ #操作光谱仪
+ # self.dc_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ self.spectral_mode_wb_bt.clicked.connect(self.run) # 曝光 + 采集白板
+ self.spectral_mode_align_bt.clicked.connect(self.run)
+ self.spectral_mode_stop_align_bt.clicked.connect(self.stop_align) # 这个操作非常简单,耗时非常短,瞬间可回到event loop;所以不需要多线程
+ self.spectral_mode_dc_bt.clicked.connect(self.run)
+ self.spectral_mode_record_bt.clicked.connect(self.run)
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filepath_bt.clicked.connect(self.directory_select)
+ self.filename_le.editingFinished.connect(self.onchange)
+ # self.filepath_le.textEdited.connect(self.onchange)
+
+ self.cwd = system_setting.spectral_dir
+
+ def temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+ except:
+ traceback.print_exc()
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def stop_align(self):
+ SpectralCameraOperation.align = False
+
+ def run(self):
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.statu_tb.append('曝光/白板...')
+ self.logger.info('曝光/白板...')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.statu_tb.append('align...')
+ self.logger.info('align...')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.statu_tb.append('采集暗电流...')
+ self.logger.info('采集暗电流...')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('采集光谱...')
+ self.logger.info('采集光谱...')
+
+ worker = Worker(SpectralCameraOperation.start_AcquireData, camera, self.qt_sender)
+ worker.signals.finished.connect(self.operate_success)
+ worker.signals.error.connect(self.operate_failed)
+ # worker.signals.result.connect()
+
+ self.threadpool.start(worker)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.statu_tb.append('曝光/白板失败!')
+ self.logger.error('曝光/白板失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.statu_tb.append('align 失败!')
+ self.logger.error('align 失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.statu_tb.append('采集暗电流失败!')
+ self.logger.error('采集暗电流失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('采集光谱失败!')
+ self.logger.error('采集光谱失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('保存光谱失败!')
+ self.logger.error('保存光谱失败!\n%s', traceback_info[2])
+ QMessageBox.information(self, '提示', '请输入正确的光谱名!', QMessageBox.Yes)
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.statu_tb.append('曝光/白板成功!')
+ self.logger.info('曝光/白板成功!')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.statu_tb.append('align successfully!')
+ self.logger.info('align successfully!')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.statu_tb.append('采集暗电流成功!')
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.statu_tb.append('采集光谱成功!')
+ self.logger.info('采集光谱成功!')
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ filename = self.filename_le.text()
+ system_setting.default_spectral_name = filename
+ if filename != '':
+ system_setting.signals.spectral_signal.emit({'default_spectral_name': filename})
+ self.logger.info('选择光谱保存路径!')
+
+ def directory_select(self):
+ dirpath = QFileDialog.getExistingDirectory(self, '选择存储路径文件夹', self.cwd)
+
+ # 当在文件夹选择窗口中点击取消时,不重设路径
+ if dirpath != '':
+ self.cwd = dirpath
+
+ self.filepath_le.setText(dirpath)
+ system_setting.signals.spectral_signal.emit({'spectral_dir': dirpath})
+ self.logger.info('选择光谱保存路径!')
+
+
+# 影像模式类:相关的函数和变量
+class CameraOperation(object):
+
+ # 传感器有效范围
+ # startRow = 339
+ # endRow = 639
+ # startColumn = 285
+ # endColumn = 1650
+ # 影像中400-560列:685-845
+ startRow = 339
+ endRow = 639
+ startColumn = 285
+ endColumn = 1649
+
+ # 转辐亮度
+ rad_or_not = False
+ # img_gain = r'D:\py_program\corning410\corning410_radiance_calibration\jfq_dn_gain'
+ img_gain = get_resource_path('./data/jfq_dn_gain')
+ print(img_gain)
+ _, _, gain = ImageReaderWriter.read_img(img_gain)
+ gain = gain.astype(np.float)
+ cal_it = 6059
+ target_it = None
+ gain_scale = None
+
+ @classmethod
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposure_gain_framerate(cls, cam):
+ # settings,cam.set_param("exposure",10000)
+ cam.set_framerate(int(system_setting.framerate))
+ cam.set_exposure(int(system_setting.exposure_time)) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(int(float(system_setting.gain))) #int('0.0')会报错,int(float('0.0'))不会报错
+
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ # ('Framerate: ' + str(cam.get_framerate()) + ' FPS')这样连接字符串会浪费内存
+ enter_window_instance.image_window_instance.statu_tb.append("%s%s%s" % ('Framerate: ', str(cam.get_framerate()), ' FPS'))
+ enter_window_instance.image_window_instance.statu_tb.append("%s%s%s" % ('Exposure: ', str(cam.get_exposure()), ' us'))
+ enter_window_instance.image_window_instance.statu_tb.append("%s%s%s" % ('Gain: ', str(cam.get_gain()), ' dB'))
+
+ # 开始采集数据
+ framenumber_input = 100 # 随便给个初始值(初始值要和framenumber_le控件初始值一致),从image_window获取的手动输入的帧数
+ image_dc = 1 # 随便给个初始值,此变量用于存储采集到的暗电流影像
+ image_wb = 1 # 随便给个初始值,此变量用于存储采集到的白板影像
+ focus = True # 用于停止调焦
+ record = True # 用于停止采集
+ img_datatype = 12 # 在头文件中确定影像数据类型
+ # bin相关设置
+ bin_spectral = 1 # 光谱bin
+ bin_spatial = 1 # 空间bin
+ k = np.arange(endRow - startRow)[0::bin_spectral]
+ l = np.arange(endColumn - startColumn)[0::bin_spatial]
+
+ rgb = np.zeros((3, int(framenumber_input), int((endColumn - startColumn) / bin_spatial)))
+
+ autoexposure_feedback = 0 # 指示:自动曝光所得到的shutter值是否为最大;如果为最大→值设置为1
+ @classmethod
+ def start_AcquireData(cls, cam, qt_sender): # qt_sender是指qt窗口中事件的发生者
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ # 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+ # 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype(' int(1 / int(system_setting.framerate) * 10**6):
+ cam.set_exposure(int(1 / int(system_setting.framerate) * 10**6))
+ cls.autoexposure_feedback = 1
+
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+
+ print('Framerate was set to %i FPS' % cam.get_framerate())
+ print('Exposure was set to %i us' % cam.get_exposure())
+ print('Gain was set to %i dB' % cam.get_gain())
+
+ # 如果点击“调焦”按钮
+ if qt_sender == 'image_mode_focus_bt':
+ # cls.set_exposureTime(cam)
+
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not cls.focus:
+ cls.focus = True
+
+ cam.start_acquisition()
+
+ while cls.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container = image_raw_numpy[system_setting.start_row:system_setting.end_row, system_setting.start_column:system_setting.end_column]
+
+ try:
+ # enter_window_instance.image_window_instance.myImageFigure.plot(image_container)
+ # enter_window_instance.image_window_instance.myImageFigure.draw()
+
+ enter_window_instance.image_window_instance.myImageFigure.setImage(image_container)
+
+ enter_window_instance.image_window_instance.myFocusFigure.plot_wrap(image_container[150, :])
+ except Exception:
+ traceback.print_exc()
+
+ # 如果点击“白板”按钮,采集并保存白板影像到image_wb
+ if qt_sender == 'image_mode_wb_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[system_setting.start_row:system_setting.end_row, system_setting.start_column:system_setting.end_column]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ # 白板扣除暗电流放在暗电流采集中
+ cls.image_wb = image_container_bin
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'image_mode_dc_bt':
+ framenumber = 10
+ image_container = np.empty((cls.endRow - cls.startRow, framenumber, cls.endColumn - cls.startColumn))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[system_setting.start_row:system_setting.end_row, system_setting.start_column:system_setting.end_column]
+
+ image_container = image_container.mean(axis=1)
+
+ # 光谱bin和空间bin
+ if cls.bin_spectral != 1:
+ image_container_bin_spectral = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral), cls.endColumn - cls.startColumn))
+ image_container_bin = np.zeros(
+ (int((cls.endRow - cls.startRow) / cls.bin_spectral),
+ int((cls.endColumn - cls.startColumn) / cls.bin_spatial)))
+
+ for i in range(image_container_bin_spectral.shape[0]):
+ for j in range(cls.bin_spectral):
+ image_container_bin_spectral[i] += image_container[cls.k[i] + j]
+ # 光谱bin完成后,进行空间bin
+ for i in range(image_container_bin.shape[1]):
+ for j in range(cls.bin_spatial):
+ image_container_bin[:, i] += image_container_bin_spectral[:, cls.l[i] + j]
+ else:
+ image_container_bin = image_container
+
+ cls.image_dc = image_container_bin
+ cls.image_wb = cls.image_wb - cls.image_dc
+
+ # 如果点击“采集”按钮,自动去除暗电流,并且转化成反射率
+ if qt_sender == 'image_mode_record_bt':
+ frameCount = 1 # 统计采集的帧数,用于停止采集使用
+
+ # 当停止采集后,再次开始采集需要将cls.record的值从False变为True
+ if not cls.record:
+ cls.record = True
+
+ # 开始马达
+ try:
+ # D:\py27_program\arcus\ArcusDevice.py
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' CLR PX=0 EO=1 J+'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' CLR PX=0 EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+ except:
+ pass
+
+ # 开始采集数据 并且 将数据写入到硬盘中
+ cam.start_acquisition()
+ with open('corning410_test', 'wb') as f:
+
+ print('Starting data acquisition...')
+ startTime = datetime.datetime.now()
+
+ while cls.record:
+ cam.get_image(img) # get data and pass them from camera to img
+ # image_raw_numpy.dtype -> dtype('
+
+ arcus_ui
+
+
+
+ 0
+ 0
+ 354
+ 171
+
+
+
+ MainWindow
+
+
+
+
+
+ 100
+ 90
+ 61
+ 21
+
+
+
+ 左
+
+
+
+
+
+ 170
+ 90
+ 61
+ 23
+
+
+
+ 右
+
+
+
+
+
+ 101
+ 10
+ 131
+ 20
+
+
+
+
+
+
+ 100
+ 40
+ 131
+ 20
+
+
+
+ Qt::Horizontal
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v25/ui/enter_window.py b/record_system_v25/ui/enter_window.py
new file mode 100644
index 0000000..9f5f1cd
--- /dev/null
+++ b/record_system_v25/ui/enter_window.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'enter_window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_enter_Window(object):
+ def setupUi(self, enter_Window):
+ enter_Window.setObjectName("enter_Window")
+ enter_Window.resize(651, 474)
+ self.centralwidget = QtWidgets.QWidget(enter_Window)
+ self.centralwidget.setObjectName("centralwidget")
+ self.image_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.image_mode_bt.setGeometry(QtCore.QRect(200, 180, 111, 51))
+ self.image_mode_bt.setObjectName("image_mode_bt")
+ self.spectral_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.spectral_mode_bt.setGeometry(QtCore.QRect(360, 180, 111, 51))
+ self.spectral_mode_bt.setObjectName("spectral_mode_bt")
+ self.camstatus_tb = QtWidgets.QTextBrowser(self.centralwidget)
+ self.camstatus_tb.setGeometry(QtCore.QRect(200, 240, 271, 81))
+ self.camstatus_tb.setObjectName("camstatus_tb")
+ enter_Window.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(enter_Window)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 651, 26))
+ self.menubar.setObjectName("menubar")
+ enter_Window.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(enter_Window)
+ self.statusbar.setObjectName("statusbar")
+ enter_Window.setStatusBar(self.statusbar)
+ self.actionwew_e = QtWidgets.QAction(enter_Window)
+ self.actionwew_e.setObjectName("actionwew_e")
+
+ self.retranslateUi(enter_Window)
+ QtCore.QMetaObject.connectSlotsByName(enter_Window)
+
+ def retranslateUi(self, enter_Window):
+ _translate = QtCore.QCoreApplication.translate
+ enter_Window.setWindowTitle(_translate("enter_Window", "主窗口"))
+ self.image_mode_bt.setText(_translate("enter_Window", "影像模式"))
+ self.spectral_mode_bt.setText(_translate("enter_Window", "光谱模式"))
+ self.actionwew_e.setText(_translate("enter_Window", "wew e"))
diff --git a/record_system_v25/ui/enter_window.ui b/record_system_v25/ui/enter_window.ui
new file mode 100644
index 0000000..4c39418
--- /dev/null
+++ b/record_system_v25/ui/enter_window.ui
@@ -0,0 +1,73 @@
+
+
+ enter_Window
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+
+
+ 200
+ 180
+ 111
+ 51
+
+
+
+ 影像模式
+
+
+
+
+
+ 360
+ 180
+ 111
+ 51
+
+
+
+ 光谱模式
+
+
+
+
+
+ 200
+ 240
+ 271
+ 81
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v25/ui/image_Window.py b/record_system_v25/ui/image_Window.py
new file mode 100644
index 0000000..f877b4e
--- /dev/null
+++ b/record_system_v25/ui/image_Window.py
@@ -0,0 +1,268 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window(object):
+ def setupUi(self, image_Window):
+ image_Window.setObjectName("image_Window")
+ image_Window.setEnabled(True)
+ image_Window.resize(1179, 683)
+ image_Window.setMouseTracking(False)
+ image_Window.setFocusPolicy(QtCore.Qt.NoFocus)
+ image_Window.setAutoFillBackground(False)
+ image_Window.setSizeGripEnabled(False)
+ image_Window.setModal(False)
+ self.gridLayout = QtWidgets.QGridLayout(image_Window)
+ self.gridLayout.setObjectName("gridLayout")
+ self.groupBox_5 = QtWidgets.QGroupBox(image_Window)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
+ self.groupBox_5.setSizePolicy(sizePolicy)
+ self.groupBox_5.setObjectName("groupBox_5")
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.groupBox_5)
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ self.hum_label = QtWidgets.QLabel(self.groupBox_5)
+ self.hum_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.horizontalLayout_4.addWidget(self.hum_label)
+ spacerItem = QtWidgets.QSpacerItem(374, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem)
+ self.splitter_2 = QtWidgets.QSplitter(self.groupBox_5)
+ self.splitter_2.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter_2.setObjectName("splitter_2")
+ self.layoutWidget = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.label = QtWidgets.QLabel(self.layoutWidget)
+ self.label.setObjectName("label")
+ self.verticalLayout.addWidget(self.label)
+ self.label_4 = QtWidgets.QLabel(self.layoutWidget)
+ self.label_4.setObjectName("label_4")
+ self.verticalLayout.addWidget(self.label_4)
+ self.layoutWidget1 = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget1.setObjectName("layoutWidget1")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.layoutWidget1)
+ self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.filepath_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filepath_le.setReadOnly(True)
+ self.filepath_le.setObjectName("filepath_le")
+ self.verticalLayout_2.addWidget(self.filepath_le)
+ self.filename_le = QtWidgets.QLineEdit(self.layoutWidget1)
+ self.filename_le.setObjectName("filename_le")
+ self.verticalLayout_2.addWidget(self.filename_le)
+ self.layoutWidget2 = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget2.setObjectName("layoutWidget2")
+ self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.layoutWidget2)
+ self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_3.setObjectName("verticalLayout_3")
+ self.filepath_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.filepath_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.filepath_bt.setAutoDefault(False)
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.verticalLayout_3.addWidget(self.filepath_bt)
+ self.save_bt = QtWidgets.QPushButton(self.layoutWidget2)
+ self.save_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.save_bt.setAutoDefault(False)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout_3.addWidget(self.save_bt)
+ self.layoutWidget3 = QtWidgets.QWidget(self.splitter_2)
+ self.layoutWidget3.setObjectName("layoutWidget3")
+ self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.layoutWidget3)
+ self.verticalLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout_7.setObjectName("verticalLayout_7")
+ self.t_label = QtWidgets.QLabel(self.layoutWidget3)
+ self.t_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.t_label.setObjectName("t_label")
+ self.verticalLayout_7.addWidget(self.t_label)
+ self.horizontalLayout_4.addWidget(self.splitter_2)
+ spacerItem1 = QtWidgets.QSpacerItem(374, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_4.addItem(spacerItem1)
+ self.gridLayout.addWidget(self.groupBox_5, 0, 0, 1, 1)
+ self.splitter = QtWidgets.QSplitter(image_Window)
+ self.splitter.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter.setObjectName("splitter")
+ self.groupBox_3 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_3.sizePolicy().hasHeightForWidth())
+ self.groupBox_3.setSizePolicy(sizePolicy)
+ self.groupBox_3.setMinimumSize(QtCore.QSize(0, 0))
+ self.groupBox_3.setMaximumSize(QtCore.QSize(2000, 16777215))
+ self.groupBox_3.setObjectName("groupBox_3")
+ self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.groupBox_3)
+ self.verticalLayout_4.setObjectName("verticalLayout_4")
+ self.groupBox = QtWidgets.QGroupBox(self.groupBox_3)
+ self.groupBox.setObjectName("groupBox")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.horizontalLayout.addLayout(self.image_glo)
+ self.verticalLayout_4.addWidget(self.groupBox)
+ self.statu_tb = QtWidgets.QTextBrowser(self.groupBox_3)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.statu_tb.sizePolicy().hasHeightForWidth())
+ self.statu_tb.setSizePolicy(sizePolicy)
+ self.statu_tb.setMaximumSize(QtCore.QSize(8777215, 100))
+ self.statu_tb.setReadOnly(True)
+ self.statu_tb.setObjectName("statu_tb")
+ self.verticalLayout_4.addWidget(self.statu_tb)
+ self.groupBox_4 = QtWidgets.QGroupBox(self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_4.sizePolicy().hasHeightForWidth())
+ self.groupBox_4.setSizePolicy(sizePolicy)
+ self.groupBox_4.setObjectName("groupBox_4")
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.groupBox_4)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.groupBox_2 = QtWidgets.QGroupBox(self.groupBox_4)
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox_2)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.horizontalLayout_2.addLayout(self.focus_glo)
+ self.verticalLayout_5.addWidget(self.groupBox_2)
+ self.groupBox_6 = QtWidgets.QGroupBox(self.groupBox_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_6.sizePolicy().hasHeightForWidth())
+ self.groupBox_6.setSizePolicy(sizePolicy)
+ self.groupBox_6.setObjectName("groupBox_6")
+ self.horizontalLayout_5 = QtWidgets.QHBoxLayout(self.groupBox_6)
+ self.horizontalLayout_5.setObjectName("horizontalLayout_5")
+ self.groupBox_7 = QtWidgets.QGroupBox(self.groupBox_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
+ self.groupBox_7.setSizePolicy(sizePolicy)
+ self.groupBox_7.setMaximumSize(QtCore.QSize(500, 500))
+ self.groupBox_7.setObjectName("groupBox_7")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_7)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.verticalLayout_6 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_6.setObjectName("verticalLayout_6")
+ self.label_3 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.verticalLayout_6.addWidget(self.label_3)
+ self.image_mode_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_focus_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_focus_bt.setAutoDefault(False)
+ self.image_mode_focus_bt.setObjectName("image_mode_focus_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_focus_bt)
+ self.image_mode_exposureTime_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_exposureTime_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_exposureTime_bt.setAutoDefault(False)
+ self.image_mode_exposureTime_bt.setObjectName("image_mode_exposureTime_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_exposureTime_bt)
+ self.label_5 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_5.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_5.setObjectName("label_5")
+ self.verticalLayout_6.addWidget(self.label_5)
+ self.image_mode_wb_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_wb_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_wb_bt.setAutoDefault(False)
+ self.image_mode_wb_bt.setObjectName("image_mode_wb_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_wb_bt)
+ self.label_2 = QtWidgets.QLabel(self.groupBox_7)
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.verticalLayout_6.addWidget(self.label_2)
+ self.image_mode_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_record_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_record_bt.setAutoDefault(False)
+ self.image_mode_record_bt.setObjectName("image_mode_record_bt")
+ self.verticalLayout_6.addWidget(self.image_mode_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_6)
+ self.verticalLayout_8 = QtWidgets.QVBoxLayout()
+ self.verticalLayout_8.setObjectName("verticalLayout_8")
+ self.framerate_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.verticalLayout_8.addWidget(self.framerate_le)
+ self.image_mode_stop_focus_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_stop_focus_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_stop_focus_bt.setAutoDefault(False)
+ self.image_mode_stop_focus_bt.setObjectName("image_mode_stop_focus_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_stop_focus_bt)
+ self.exposure_time_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.exposure_time_le.setObjectName("exposure_time_le")
+ self.verticalLayout_8.addWidget(self.exposure_time_le)
+ self.gain_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.gain_le.setObjectName("gain_le")
+ self.verticalLayout_8.addWidget(self.gain_le)
+ self.image_mode_dc_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_dc_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_dc_bt.setAutoDefault(False)
+ self.image_mode_dc_bt.setObjectName("image_mode_dc_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_dc_bt)
+ self.framenumber_le = QtWidgets.QLineEdit(self.groupBox_7)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.verticalLayout_8.addWidget(self.framenumber_le)
+ self.image_mode_motor_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_motor_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_motor_bt.setAutoDefault(False)
+ self.image_mode_motor_bt.setObjectName("image_mode_motor_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_motor_bt)
+ self.image_mode_stop_record_bt = QtWidgets.QPushButton(self.groupBox_7)
+ self.image_mode_stop_record_bt.setFocusPolicy(QtCore.Qt.ClickFocus)
+ self.image_mode_stop_record_bt.setAutoDefault(False)
+ self.image_mode_stop_record_bt.setObjectName("image_mode_stop_record_bt")
+ self.verticalLayout_8.addWidget(self.image_mode_stop_record_bt)
+ self.horizontalLayout_3.addLayout(self.verticalLayout_8)
+ self.horizontalLayout_5.addWidget(self.groupBox_7)
+ spacerItem2 = QtWidgets.QSpacerItem(261, 17, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_5.addItem(spacerItem2)
+ self.verticalLayout_5.addWidget(self.groupBox_6)
+ self.gridLayout.addWidget(self.splitter, 1, 0, 1, 1)
+
+ self.retranslateUi(image_Window)
+ QtCore.QMetaObject.connectSlotsByName(image_Window)
+
+ def retranslateUi(self, image_Window):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window.setWindowTitle(_translate("image_Window", "影像窗口"))
+ self.groupBox_5.setTitle(_translate("image_Window", "GroupBox"))
+ self.hum_label.setText(_translate("image_Window", "湿度:无数据"))
+ self.label.setText(_translate("image_Window", "保存路径"))
+ self.label_4.setText(_translate("image_Window", "文件名"))
+ self.filepath_bt.setText(_translate("image_Window", "浏览"))
+ self.save_bt.setText(_translate("image_Window", "保存"))
+ self.t_label.setText(_translate("image_Window", "温度:无数据"))
+ self.groupBox_3.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox.setTitle(_translate("image_Window", "图像"))
+ self.groupBox_4.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_2.setTitle(_translate("image_Window", "光谱"))
+ self.groupBox_6.setTitle(_translate("image_Window", "GroupBox"))
+ self.groupBox_7.setTitle(_translate("image_Window", "GroupBox"))
+ self.label_3.setText(_translate("image_Window", "帧率"))
+ self.image_mode_focus_bt.setText(_translate("image_Window", "调焦"))
+ self.image_mode_exposureTime_bt.setText(_translate("image_Window", "曝光"))
+ self.label_5.setText(_translate("image_Window", "gain"))
+ self.image_mode_wb_bt.setText(_translate("image_Window", "白板"))
+ self.label_2.setText(_translate("image_Window", "帧数"))
+ self.image_mode_record_bt.setText(_translate("image_Window", "采集"))
+ self.image_mode_stop_focus_bt.setText(_translate("image_Window", "停止调焦"))
+ self.image_mode_dc_bt.setText(_translate("image_Window", "暗电流"))
+ self.image_mode_motor_bt.setText(_translate("image_Window", "马达"))
+ self.image_mode_stop_record_bt.setText(_translate("image_Window", "停止采集"))
diff --git a/record_system_v25/ui/image_Window.ui b/record_system_v25/ui/image_Window.ui
new file mode 100644
index 0000000..0b93dd3
--- /dev/null
+++ b/record_system_v25/ui/image_Window.ui
@@ -0,0 +1,468 @@
+
+
+ image_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 1179
+ 683
+
+
+
+ false
+
+
+ Qt::NoFocus
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 湿度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 374
+ 20
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
-
+
+
+ 保存路径
+
+
+
+ -
+
+
+ 文件名
+
+
+
+
+
+
+
+ -
+
+
+ true
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 浏览
+
+
+ false
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 保存
+
+
+ false
+
+
+
+
+
+
+
+ -
+
+
+ 温度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 374
+ 20
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 2000
+ 16777215
+
+
+
+ GroupBox
+
+
+
-
+
+
+ 图像
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 8777215
+ 100
+
+
+
+ true
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+ -
+
+
+ 光谱
+
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ GroupBox
+
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 500
+ 500
+
+
+
+ GroupBox
+
+
+
-
+
+
-
+
+
+ 帧率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 调焦
+
+
+ false
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 曝光
+
+
+ false
+
+
+
+ -
+
+
+ gain
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 白板
+
+
+ false
+
+
+
+ -
+
+
+ 帧数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 采集
+
+
+ false
+
+
+
+
+
+ -
+
+
-
+
+
+ false
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 停止调焦
+
+
+ false
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 暗电流
+
+
+ false
+
+
+
+ -
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 马达
+
+
+ false
+
+
+
+ -
+
+
+ Qt::ClickFocus
+
+
+ 停止采集
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 261
+ 17
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v25/ui/image_Window_phone.ui b/record_system_v25/ui/image_Window_phone.ui
new file mode 100644
index 0000000..3b5ed09
--- /dev/null
+++ b/record_system_v25/ui/image_Window_phone.ui
@@ -0,0 +1,1083 @@
+
+
+ image_Window_phone
+
+
+ true
+
+
+
+ 0
+ 0
+ 525
+ 1174
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 调 焦
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 白 板
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 保 存
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 积分时间
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+ false
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 160
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ <
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ >
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 233
+ 12
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 光谱仪
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 马达
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v25/ui/spectral_Window.py b/record_system_v25/ui/spectral_Window.py
new file mode 100644
index 0000000..6e89899
--- /dev/null
+++ b/record_system_v25/ui/spectral_Window.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window(object):
+ def setupUi(self, spectral_Window):
+ spectral_Window.setObjectName("spectral_Window")
+ spectral_Window.resize(820, 545)
+ self.label = QtWidgets.QLabel(spectral_Window)
+ self.label.setGeometry(QtCore.QRect(54, 10, 51, 20))
+ self.label.setObjectName("label")
+ self.filepath_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filepath_le.setGeometry(QtCore.QRect(131, 10, 261, 21))
+ self.filepath_le.setObjectName("filepath_le")
+ self.label_2 = QtWidgets.QLabel(spectral_Window)
+ self.label_2.setGeometry(QtCore.QRect(54, 40, 41, 20))
+ self.label_2.setObjectName("label_2")
+ self.filename_le = QtWidgets.QLineEdit(spectral_Window)
+ self.filename_le.setGeometry(QtCore.QRect(131, 40, 261, 21))
+ self.filename_le.setObjectName("filename_le")
+ self.filepath_bt = QtWidgets.QPushButton(spectral_Window)
+ self.filepath_bt.setGeometry(QtCore.QRect(401, 10, 71, 21))
+ self.filepath_bt.setObjectName("filepath_bt")
+ self.statu_tb = QtWidgets.QTextBrowser(spectral_Window)
+ self.statu_tb.setGeometry(QtCore.QRect(620, 240, 161, 301))
+ self.statu_tb.setObjectName("statu_tb")
+ self.tabWidget = QtWidgets.QTabWidget(spectral_Window)
+ self.tabWidget.setGeometry(QtCore.QRect(10, 70, 591, 441))
+ self.tabWidget.setObjectName("tabWidget")
+ self.tab = QtWidgets.QWidget()
+ self.tab.setObjectName("tab")
+ self.gridLayoutWidget = QtWidgets.QWidget(self.tab)
+ self.gridLayoutWidget.setGeometry(QtCore.QRect(0, 0, 581, 411))
+ self.gridLayoutWidget.setObjectName("gridLayoutWidget")
+ self.spe_glo = QtWidgets.QGridLayout(self.gridLayoutWidget)
+ self.spe_glo.setContentsMargins(0, 0, 0, 0)
+ self.spe_glo.setObjectName("spe_glo")
+ self.tabWidget.addTab(self.tab, "")
+ self.tab_2 = QtWidgets.QWidget()
+ self.tab_2.setObjectName("tab_2")
+ self.gridLayoutWidget_2 = QtWidgets.QWidget(self.tab_2)
+ self.gridLayoutWidget_2.setGeometry(QtCore.QRect(-1, -1, 581, 411))
+ self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2")
+ self.align_glo = QtWidgets.QGridLayout(self.gridLayoutWidget_2)
+ self.align_glo.setContentsMargins(0, 0, 0, 0)
+ self.align_glo.setObjectName("align_glo")
+ self.tabWidget.addTab(self.tab_2, "")
+ self.layoutWidget = QtWidgets.QWidget(spectral_Window)
+ self.layoutWidget.setGeometry(QtCore.QRect(610, 90, 195, 135))
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.spectral_mode_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_align_bt.setObjectName("spectral_mode_align_bt")
+ self.gridLayout.addWidget(self.spectral_mode_align_bt, 0, 0, 1, 1)
+ self.spectral_mode_stop_align_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_stop_align_bt.setObjectName("spectral_mode_stop_align_bt")
+ self.gridLayout.addWidget(self.spectral_mode_stop_align_bt, 0, 1, 1, 1)
+ self.spectral_mode_wb_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_wb_bt.setObjectName("spectral_mode_wb_bt")
+ self.gridLayout.addWidget(self.spectral_mode_wb_bt, 1, 0, 1, 2)
+ self.spectral_mode_dc_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_dc_bt.setObjectName("spectral_mode_dc_bt")
+ self.gridLayout.addWidget(self.spectral_mode_dc_bt, 2, 0, 1, 2)
+ self.spectral_mode_record_bt = QtWidgets.QPushButton(self.layoutWidget)
+ self.spectral_mode_record_bt.setObjectName("spectral_mode_record_bt")
+ self.gridLayout.addWidget(self.spectral_mode_record_bt, 3, 0, 1, 2)
+ self.t_label = QtWidgets.QLabel(spectral_Window)
+ self.t_label.setGeometry(QtCore.QRect(490, 11, 78, 23))
+ self.t_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.t_label.setObjectName("t_label")
+ self.hum_label = QtWidgets.QLabel(spectral_Window)
+ self.hum_label.setGeometry(QtCore.QRect(490, 40, 78, 23))
+ self.hum_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.hum_label.setObjectName("hum_label")
+
+ self.retranslateUi(spectral_Window)
+ self.tabWidget.setCurrentIndex(0)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window)
+
+ def retranslateUi(self, spectral_Window):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window.setWindowTitle(_translate("spectral_Window", "光谱窗口"))
+ self.label.setText(_translate("spectral_Window", "保存路径"))
+ self.label_2.setText(_translate("spectral_Window", "文件名"))
+ self.filepath_bt.setText(_translate("spectral_Window", "浏览"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("spectral_Window", "spe"))
+ self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("spectral_Window", "align"))
+ self.spectral_mode_align_bt.setText(_translate("spectral_Window", "align"))
+ self.spectral_mode_stop_align_bt.setText(_translate("spectral_Window", "stop align"))
+ self.spectral_mode_wb_bt.setText(_translate("spectral_Window", "曝光/白板"))
+ self.spectral_mode_dc_bt.setText(_translate("spectral_Window", "暗电流"))
+ self.spectral_mode_record_bt.setText(_translate("spectral_Window", "采集"))
+ self.t_label.setText(_translate("spectral_Window", "温度:无数据"))
+ self.hum_label.setText(_translate("spectral_Window", "湿度:无数据"))
diff --git a/record_system_v25/ui/spectral_Window.ui b/record_system_v25/ui/spectral_Window.ui
new file mode 100644
index 0000000..378d713
--- /dev/null
+++ b/record_system_v25/ui/spectral_Window.ui
@@ -0,0 +1,215 @@
+
+
+ spectral_Window
+
+
+
+ 0
+ 0
+ 820
+ 545
+
+
+
+ 光谱窗口
+
+
+
+
+ 54
+ 10
+ 51
+ 20
+
+
+
+ 保存路径
+
+
+
+
+
+ 131
+ 10
+ 261
+ 21
+
+
+
+ true
+
+
+
+
+
+ 54
+ 40
+ 41
+ 20
+
+
+
+ 文件名
+
+
+
+
+
+ 131
+ 40
+ 261
+ 21
+
+
+
+
+
+
+ 401
+ 10
+ 71
+ 21
+
+
+
+ 浏览
+
+
+
+
+
+ 620
+ 240
+ 161
+ 301
+
+
+
+
+
+
+ 10
+ 70
+ 591
+ 441
+
+
+
+ 0
+
+
+
+ spe
+
+
+
+
+ 0
+ 0
+ 581
+ 411
+
+
+
+
+
+
+
+ align
+
+
+
+
+ -1
+ -1
+ 581
+ 411
+
+
+
+
+
+
+
+
+
+ 610
+ 90
+ 195
+ 135
+
+
+
+ -
+
+
+ align
+
+
+
+ -
+
+
+ stop align
+
+
+
+ -
+
+
+ 曝光/白板
+
+
+
+ -
+
+
+ 暗电流
+
+
+
+ -
+
+
+ 采集
+
+
+
+
+
+
+
+
+ 490
+ 11
+ 78
+ 23
+
+
+
+ 温度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+ 490
+ 40
+ 78
+ 23
+
+
+
+ 湿度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
diff --git a/record_system_v25/ui/spectral_Window_phone.ui b/record_system_v25/ui/spectral_Window_phone.ui
new file mode 100644
index 0000000..402fd57
--- /dev/null
+++ b/record_system_v25/ui/spectral_Window_phone.ui
@@ -0,0 +1,377 @@
+
+
+ spectral_Window_phone
+
+
+
+ 0
+ 0
+ 568
+ 1144
+
+
+
+ 光谱窗口
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 600
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝光/白板
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗电流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ /*background-color:rgb(14 , 135 , 228);*/
+ background-color:red;
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采集
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 150
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 25
+
+
+
+ 文件名
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 61
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ 温度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+ -
+
+
+ 湿度:无数据
+
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v26/2record_system_v26.py b/record_system_v26/2record_system_v26.py
new file mode 100644
index 0000000..37f1246
--- /dev/null
+++ b/record_system_v26/2record_system_v26.py
@@ -0,0 +1,2215 @@
+# -*- coding:utf-8 -*-
+
+'''
+在2record system_v2.2的基础上更新:
+1、优化界面美观
+2、极大的优化了代码结构:充分利用了类的封装特性,降低了耦合性;解决了界面显示图像和光谱的问题;
+3、设置ximea的有效输出窗口,以提高帧率
+4、设置芯片中bin,以减轻电脑的运算量
+5、
+6、
+7、
+'''
+
+# 内置包
+import os, sys, functools, re, shutil, traceback, time
+import subprocess
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+import logging
+
+# 三方包
+import numpy as np
+from osgeo import gdal
+from ximea import xiapi
+import configparser
+import serial
+import serial.tools.list_ports
+from serial.serialutil import SerialBase, SerialException
+
+# 界面包
+import qimage2ndarray
+from PyQt5.QtCore import Qt, QObject, QThreadPool, QTimer, QRegExp, pyqtSignal
+# from PyQt5.QtCore import QRectF, pyqtSignal, QRunnable, pyqtSlot, QT_VERSION_STR
+from PyQt5.QtGui import QIntValidator, QRegExpValidator, QPixmap, QImage, QPainterPath
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
+
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from library.matplotlib_display_image_spectral import MatplotlibSpectralViewer, MatplotlibImageViewer
+
+
+# 自己写的包
+from QtImageViewer import QtImageViewer
+from QtSpectralViewer import QtSpectralViewer
+from library.multithread import Worker
+from library.image_reader_writer import ImageReaderWriter
+from library.functions import get_path, get_resource_path, return_file_path
+from library.message_box import MessageBox
+from library.config import ConfigFile
+from library.log import Log
+
+
+from record_system_v26.ui.enter_window import *
+
+# from record_system_v26.ui.image_Window import *
+from record_system_v26.ui.image_Window_phone import *
+
+# from record_system_v26.ui.spectral_Window import *
+from record_system_v26.ui.spectral_Window_phone import *
+
+
+# 主窗口
+class EnterWindow(QMainWindow, Ui_enter_Window):
+ def __init__(self, parent=None):
+ super(EnterWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+
+ self.image_mode_phone_bt.clicked.connect(self.image_window)
+
+ self.spectral_mode_bt.clicked.connect(self.spectral_window)
+
+ self.setEnabled(False) # 先设置本窗口不可用,当打开相机成功后,才设置为可用
+
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ def image_window(self):
+ self.image_window_phone_instance = ImageWindowPhone()
+ self.image_window_phone_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.image_window_phone_instance.show()
+
+ def spectral_window(self):
+ self.spectral_window_instance = SpectralWindow()
+ print(id(self.spectral_window_instance))
+ self.spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.spectral_window_instance.show()
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ self.camstatus_label.setText('相机打开成功!')
+
+ # 如果相机打开成功,界面中label颜色设置为绿色
+ self.change_lable_background_color('green')
+
+ self.setEnabled(True) # 如果相机打开成功,则窗口可用
+ elif imager_status == 1001:
+ self.camstatus_label.setText('相机打开时出现不是ximea错误的未知错误!')
+
+ # 如果相机打开成功,界面中label颜色设置为绿色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 1:
+ self.camstatus_label.setText('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ self.camstatus_label.setText('没有检测到光谱仪!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 103:
+ pass
+
+ def change_lable_background_color(self, color):
+ pattern = re.compile('background-color:rgb[(](.*)[)]')
+ old_style_sheet = self.camstatus_label.styleSheet()
+
+ if color == 'red': # 如果相机打开失败,界面中label颜色设置为红色
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0)', old_style_sheet)
+ self.camstatus_label.setStyleSheet(new_style_sheet)
+ elif color == 'green': # 如果相机打开成功,界面中label颜色设置为绿色
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0)', old_style_sheet)
+ self.camstatus_label.setStyleSheet(new_style_sheet)
+
+
+class SerialPort(QObject):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ serial_signal = pyqtSignal(object) # 建立信号,用于发射获取的温湿度
+
+ def __init__(self):
+ super(SerialPort, self).__init__()
+
+ # 获取log温度日志的文件夹
+ self.config_file_object = ConfigFile()
+
+ # log
+ self.logger = logging.getLogger('root.serial')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//temperature.log'):
+ with open(self.config_file_object.log_dir + '//temperature.log', 'w') as f:
+ pass
+
+ formatter1 = logging.Formatter('%(asctime)s %(message)s')
+ temperature_file_handler = logging.FileHandler(self.config_file_object.log_dir + '//temperature.log') # 输出到文件
+ temperature_file_handler.setLevel(logging.DEBUG)
+ temperature_file_handler.setFormatter(formatter1)
+
+ self.logger.addHandler(temperature_file_handler)
+
+ self.connect_number = 0 # 记录打开串口的次数
+ self.serial_port = self.open_serial_port()
+
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.receiver_data_from_port)
+ self.timer.start(1000)
+
+ def open_serial_port(self):
+ self.connect_number += 1
+ port_list = list(serial.tools.list_ports.comports()) # 列出所有可用串口
+ # print(port_list)
+
+ if len(port_list) > 0: # 如果可用串口 >0 个
+ # 打印出所有串口的信息
+ for i in range(0, len(port_list)):
+ print(port_list[i])
+
+ # 打开第一个串口
+ ser = serial.Serial(port_list[0].device)
+ # print('温湿度传感器打开成功!')
+ return ser
+ elif len(port_list) == 0: # 如果可用串口为0个
+ if self.connect_number == 1:
+ self.logger.info('无可用串口,温湿度传感器不可用!')
+ else:
+ self.logger.error('串口连接上之后,断开连接!')
+ return 1 # 如果返回1,则代表没有可用串口;通过1来判断不执行定时器触发:self.timer.start(1000)
+ else: # 其他没有考虑到的情况
+ return 1
+
+ def receiver_data_from_port(self):
+ '''
+ 定时器QTimer没隔1s调用此函数一次 → 让串口buffer有足够的数据等待读取
+ :return: 无返回值
+
+ 本函数功能:1、串口中接收字节数据,有两种帧 → 代表两种数据
+ 2、判断帧头位置和本帧数据类型
+ 3、判断帧尾 → 等效判断本帧数据是否完全
+ 4、如果数据帧完整 → 解析数据,将温度湿度显示到界面上和写入到文件中
+ '''
+ try:
+ if self.serial_port.in_waiting: # 如果串口buffer有数据等待读取
+ bytes_receive = self.serial_port.read(self.serial_port.inWaiting()) # 读取串口buffer的数据
+ # print(len(bytes_receive))
+
+ # 判断帧头位置,通过正则表达式
+ hex_receive = bytes_receive.hex() # 一个字节需要一个两位16进制数表示,所以:len(hex_receive) = len(bytes_receive) * 2
+ p = re.compile('5a5a*')
+ index_head = [i.start() / 2 for i in re.finditer(p, hex_receive)] # re.finditer()
+ # print(hex_receive)
+ # print(index_head)
+ except SerialException: # 程序打开时,温湿度传感器的串口工作正常;如果程序运行中拔掉串口就会出现此异常
+ self.logger.error('在程序运行中温湿度传感器的串口出现问题!')
+
+ # 再次尝试打开串口
+ self.serial_port = self.open_serial_port()
+ if not isinstance(self.serial_port, int):
+ self.logger.info('再次尝试连接温湿度传感器成功!')
+ else:
+ self.logger.info('再次尝试连接温湿度传感器失败!')
+ except AttributeError: # int object has no attribute: in_waiting
+ self.timer.stop()
+ self.logger.info('停止定时触发器!')
+ except Exception as e: # 未出现过的异常。当第一次出现时,需要编写代码处理,先写入日志文件(log)
+ self.logger.critical('未知错误!')
+ else: # 当没有捕获到异常时,代表串口数据获取成功 → 执行数据解析
+ # 解析数据
+ try:
+ if len(index_head) != 0:
+ Lux = 1.0
+ T = 1.0
+ P = 1.0
+ Hum = 1.0
+ H = 1.0
+ Lux_full = 0 # 判断光照帧的数据是否完整。0:不完整;1:完整;
+ T_full = 0 # 判断温度帧的数据是否完整。0:不完整;1:完整;
+ try:
+ for i in index_head: # 循环遍历每个帧头
+ if bytes_receive[int(i) + 2] == 21: # 0x15=21,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 8]) & 0xff == bytes_receive[int(i) + 8]: # 判断帧尾是否正确
+ # print('光照帧的帧尾正确!')
+
+ Lux_full = 1 # 如果帧尾,此帧数据数完整的
+ Lux = ((bytes_receive[int(i) + 4] << 24) | (bytes_receive[int(i) + 5] << 16) | (
+ bytes_receive[int(i) + 6] << 8) | bytes_receive[int(i) + 7]) / 100
+ if bytes_receive[int(i) + 2] == 69: # 0x45=69,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 14]) & 0xff == bytes_receive[int(i) + 14]: # 判断帧尾是否正确
+ # print('温度帧的帧尾正确!')
+
+ T_full = 1 # 当执行这段代码时,代表帧头帧尾都正常,此帧数据数完整的
+ T = ((bytes_receive[int(i) + 4] << 8) | bytes_receive[int(i) + 5]) / 100
+ P = ((bytes_receive[int(i) + 6] << 24) | (bytes_receive[int(i) + 7] << 16) | (
+ bytes_receive[int(i) + 8] << 8) | bytes_receive[
+ int(i) + 9]) / 100
+ Hum = ((bytes_receive[int(i) + 10] << 8) | bytes_receive[int(i) + 11]) / 100
+ H = ((bytes_receive[int(i) + 12] << 8) | bytes_receive[int(i) + 13]) / 100
+ except IndexError as e: # 当出现帧头,但是帧头到帧尾的数据不全 → 在判断帧尾是否正确时就会出现索引越界
+ # print('----------------------索引越界!')
+ pass
+ except Exception: # 当出现前面没有解决的异常时,前面的异常捕捉就失效。最后通过异常基类来捕捉 → 代表需要修改代码进行处理的新异常
+ # print('---------------------------------没遇见过的异常')
+ pass
+
+ # 将数据显示和写入文件
+ if Lux_full + T_full == 2: # x + y == 2代表温度帧和光照帧都完整
+ # self.t_label.setVisible(True)
+ # self.hum_label.setVisible(True)
+ # self.t_label.setText('温度:' + str(T))
+ # self.hum_label.setText('湿度:' + str(Hum))
+
+ # print('发送数据')
+
+ self.serial_signal.emit((str(T), str(Hum)))
+ self.logger.debug('%s %s', str(T), str(Hum)) # 将温湿度记录进log文件中
+
+ # print('光照强度:%f' % Lux)
+ # print('温度:%f' % T)
+ # print('气压:%f' % P)
+ # print('湿度:%f' % Hum)
+ # print('海拔:%f' % H)
+ # print()
+ elif Lux_full + T_full == 1:
+ # print('只有一个数据帧是完整的。(光照帧或者温度帧)')
+ # print()
+ pass
+ except UnboundLocalError:
+ # print(2222222222222222222222222222222)
+ # traceback.print_exc()
+ pass
+ except Exception:
+ self.logger.critical('未知错误!')
+ finally: # 不管有没有捕获到异常都会执行,一般用作资源回收
+ pass
+
+
+# 图像窗口
+class ImageWindowPhone(QDialog, Ui_image_Window_phone):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ arcus_status_signal = pyqtSignal(int) # arcus信号:0→马达未连接;1→马达连接成功;
+ plot_signal = pyqtSignal() # 采集影像时,边采集边刷新显示
+
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(ImageWindowPhone, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:此行代码必须放在show()函数之前
+
+ # 配置文件读取和写入类,配置文件读写和界面分离
+ # 1、采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取
+ # 2、并保存在此类中
+ self.config_file_object = ConfigFile()
+
+ # 数据采集保存类,采集数据并将数据保存在此类中,数据采集和界面分离
+ self.image_camera_operation = CameraOperation(self.config_file_object)
+
+ # 当配置文件读取完成后,就第一时间根据读取的配置文件设置相机曝光、帧率和gain
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+ self.initiate_arcus_speed() # 初始化arcus速度
+
+ # log
+ self.logger = logging.getLogger('root.image_phone')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//image_operate.log'):
+ with open(self.config_file_object.log_dir + '//image_operate.log', 'w') as f:
+ pass
+
+ image_operate_file_handler = logging.FileHandler(self.config_file_object.log_dir + "//image_operate.log") # 输出到文件
+ image_operate_file_handler.setLevel(logging.INFO)
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ image_operate_file_handler.setFormatter(formatter)
+
+ stream_handler = logging.StreamHandler() # 输出到控制台
+ stream_handler.setLevel(logging.DEBUG)
+ stream_handler.setFormatter(formatter)
+ self.logger.addHandler(image_operate_file_handler)
+ self.logger.addHandler(stream_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.serial_signal.connect(self.temperature)
+
+ # 采集影像时,边采集边刷新显示
+ self.plot_signal.connect(self.plotimg)
+
+ #建立进程池
+ # https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化窗口中的值
+ self.framenumber_le.setText(str(self.config_file_object.frame_number))
+ self.framerate_le.setText(str(self.config_file_object.framerate))
+ self.exposure_time_le.setText(str(self.config_file_object.exposure_time))
+ self.arcus_speed_le.setText(str(self.config_file_object.arcus_speed))
+ self.filename_le.setText(self.config_file_object.default_image_name)
+
+ # 显示影像和调焦
+ # self.myImageFigure = MatplotlibImageViewer()
+ self.myImageFigure = QtImageViewer()
+ self.myImageFigure.leftMouseButtonPressed.connect(self.handle_left_click)
+ self.image_glo.addWidget(self.myImageFigure)
+
+ # self.myFocusFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)')
+ self.myFocusFigure = QtSpectralViewer()
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ #操作光谱仪
+ ## 注释的代码没有使用多线程,所以会造成一采集数据界面就卡死的情况
+ # self.focus_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.dc_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(camera_operation.start_AcquireData, camera))
+ # self.save_bt.clicked.connect(camera_operation.savedata)
+ self.image_mode_exposureTime_bt.clicked.connect(self.run)
+ self.image_mode_focus_bt.clicked.connect(self.run)
+ # 停止调焦和采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_mode_dc_bt.clicked.connect(self.run)
+ self.image_mode_wb_bt.clicked.connect(self.run)
+ self.image_mode_record_bt.clicked.connect(self.run)
+ self.save_bt.clicked.connect(self.run)
+
+ # 手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.exposure_time_le.setValidator(QIntValidator()) # QIntValidator是一个类
+ self.framerate_le.setValidator(QIntValidator())
+ self.framenumber_le.setValidator(QIntValidator())
+
+ my_regex = QRegExp("[a-zA-Z0-9]*")
+ my_validator = QRegExpValidator(my_regex, self.filename_le)
+ self.filename_le.setValidator(my_validator)
+
+ self.exposure_time_le.editingFinished.connect(self.text_edited)
+ # self.exposure_time_le.setPlaceholderText('曝光时间')
+ self.framerate_le.editingFinished.connect(self.text_edited)
+ self.framenumber_le.editingFinished.connect(self.text_edited)
+ self.filename_le.editingFinished.connect(self.text_edited)
+
+ self.state = 0 # 光谱仪操作状态:曝光=1;暗电流=3;白板=5 → 所以只有state==9时才能开始采集影像
+ self.focus_count = 1 # 用于调焦按钮点击计数,取2的余数;当余数为1是执行调焦,当余数为0时停止调焦
+ self.record_count = 1 # 用于采集按钮点击计数,取2的余数;当余数为1是执行采集,当余数为0时停止采集;这是为了使用通过一个按钮控制开始采集和停止采集
+
+ # 马达相关操作
+ self.arcus_left_bt.pressed.connect(self.leftMove)
+ self.arcus_left_bt.released.connect(self.stop)
+ self.arcus_right_bt.pressed.connect(self.rightMove)
+ self.arcus_right_bt.released.connect(self.stop)
+
+ # self.arcus_speed_le.setText(self.arc.write('HSPD'))
+ self.arcus_speed_le.editingFinished.connect(self.text_edited)
+ self.arcus_speed_le.setValidator(QIntValidator())
+
+ # 控制两次点击后,发送命令的间隔
+ self.time = time.time()
+ self.time_interval = 1
+
+ self.plot_frame_count_multiple = 1 # 用于边采集边在页面中刷新,用于确定该显示多少帧了;如何确定该显示多少帧:self.plot_frame_count_multiple * 帧率
+
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ # 检测arcus马达的连接情况
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.test_arcus_status)
+ self.timer.start(3000)
+ self.arcus_status_signal.connect(self.response_to_arcus_status)
+
+ def test_arcus_status(self):
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' DN'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+ if 'Arcus device connected' in output.decode('utf-8'):
+ self.arcus_status_signal.emit(1)
+ elif 'No arcus devices' in output.decode('utf-8'):
+ self.arcus_status_signal.emit(0)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+ if 'Arcus device connected' in output2.decode('utf-8'):
+ self.arcus_status_signal.emit(1)
+ elif 'No arcus devices' in output2.decode('utf-8'):
+ self.arcus_status_signal.emit(0)
+
+ def response_to_arcus_status(self, arcus_status):
+ if arcus_status == 0:
+ self.arcus_status_label.setText('马达:连接失败!')
+ self.change_widget_background_color(self.arcus_status_label, 'red')
+ elif arcus_status == 1:
+ self.arcus_status_label.setText('马达:连接正常!')
+ self.change_widget_background_color(self.arcus_status_label, 'green')
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ # print('相机打开成功!')
+
+ self.camera_status_label.setText('光谱仪:正常')
+ self.change_widget_background_color(self.camera_status_label, 'green')
+ elif imager_status == 1001:
+ print('相机打开时出现不是ximea错误的未知错误!')
+ elif imager_status == 1:
+ # print('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ self.camera_status_label.setText('光谱仪:断开连接')
+ self.change_widget_background_color(self.camera_status_label, 'red')
+
+ self.setEnabled(False)
+ self.close()
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ print('没有检测到光谱仪!')
+ elif imager_status == 103:
+ pass
+
+ def leftMove(self):
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ print(time_now - self.time)
+
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J-'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' CLR EO=1 J-'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+
+ print('左移output', output)
+ print('左移error', error) # 如果没有输出内容就输出None
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+
+ print('---------------------------------------------------------')
+ print('左移出错output', output2)
+ print('左移出错error', error2)
+
+ def rightMove(self):
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J+'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' CLR EO=1 J+'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+
+ print('右移output;', type(output), output)
+ print('右移error', error)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+
+ print('---------------------------------------------------------')
+ print('右移出错output', output2)
+ print('右移出错error', error2)
+
+ def stop(self):
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py STOP'
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' STOP'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+
+ print('停止output', output)
+ print('停止error', error)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+
+ print('---------------------------------------------------------')
+ print('停止出错output', output2)
+ print('停止出错error', error2)
+
+ def handle_left_click(self, x, y):
+ # 画出光谱
+ try:
+ row = int(y)
+ column = int(x)
+ # print("Pixel (row=" + str(row) + ", column=" + str(column) + ")")
+
+ _, _, img = ImageReaderWriter.read_img('corning410_test', column, row, 1, 1)
+
+ if isinstance(img, np.ndarray): # 如果点击到图像之外,img就是NoneType,就不重画光谱
+ # print('点击有效')
+
+ self.myFocusFigure.plot_wrap(self.image_camera_operation.wave(model='array'), img[:, 0, 0])
+ except TypeError:
+ pass
+ # print('有错')
+ # self.logger.critical('TypeError:', exc_info=True)
+ except Exception:
+ self.logger.critical('点击显示光谱时出现未知错误:', exc_info=True)
+ traceback.print_exc()
+
+ # 手动修改界面中的值后,为相机重新设置如下参数:exposure, gain, framerate
+ def text_edited(self):
+ try:
+ # 将改变值1)保存到配置文件对象,供程序运行使用2)写入到配置文件,供程序下次打开读取
+ self.config_file_object.image_signal.emit(
+ {'exposure_time': int(self.exposure_time_le.text()),
+ 'framerate': int(self.framerate_le.text()), 'frame_number': int(self.framenumber_le.text()),
+ 'default_image_name': self.filename_le.text(), 'arcus_speed': self.arcus_speed_le.text()})
+ except ValueError:
+ # QMessageBox.information(self, '提示', '请输入正确的值!', QMessageBox.Yes)
+ self.x = MessageBox('请输入正确的值!')
+ except Exception:
+ self.logger.critical('设置曝光/gain/帧率/帧数时出现未知错误!', exe_info=True)
+
+ if self.sender().objectName() == 'exposure_time_le':
+ self.state = 1 # 手动改变曝光时间后,强制让用户重新采集暗电流+白板
+
+ print('exposure_time_le改变')
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if self.sender().objectName() == 'framerate_le':
+ self.state = 0 # 改变帧率后,需要重新曝光
+
+ print('framerate_le改变')
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if self.sender().objectName() == 'framenumber_le':
+ self.image_camera_operation.create_rgb()
+
+ if self.sender().objectName() == 'arcus_speed_le':
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' HSPD=' + str(self.arcus_speed_le.text())
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('改变速度ok!')
+
+ def initiate_arcus_speed(self):
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' HSPD=' + str(self.config_file_object.arcus_speed)
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('初始化速度ok!')
+
+ def temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+
+ self.change_widget_background_color(self.t_label, 'green')
+ self.change_widget_background_color(self.hum_label, 'green')
+ except:
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def timer_start(self):
+ '''
+ 本函数目的是在self.timer.start(1000)外包裹一层(有点装饰器的感觉),加入判断:
+ 1、如果self.serial_port为串口类型,就触发定时器self.timer.start(1000)
+ 2、如果self.serial_port == 1(为int类型),则代表硬件中没有温湿度传感器,就没必要触发定时器self.timer.start(1000)
+ :return: 无返回值
+ '''
+
+ if isinstance(self.serial_port, serial.serialwin32.Serial):
+ self.timer.start(1000)
+ elif isinstance(self.serial_port, int):
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ else:
+ pass
+
+ def plotimg(self):
+ try:
+ if self.qt_sender == 'image_mode_record_bt':
+ plot = self.plot_frame_count_multiple * self.config_file_object.framerate
+
+ img = np.dstack((self.image_camera_operation.rgb[2, 0:plot, :], self.image_camera_operation.rgb[1, 0:plot, :],
+ self.image_camera_operation.rgb[0, 0:plot, :]))
+
+ self.myImageFigure.setImage(img)
+
+ self.plot_frame_count_multiple += 1
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.myImageFigure.setImage(self.image_camera_operation.image_container)
+
+ n = int(self.image_camera_operation.image_container.shape[0] / 2)
+ self.myFocusFigure.plot_wrap(self.image_camera_operation.image_container[n, :])
+
+ # worker = Worker(self.myImageFigure.setImage, self.image_camera_operation.image_container)
+ # self.threadpool.start(worker)
+ except:
+ self.logger.critical('未知错误--界面中绘制影像和光谱时!\n%s', exc_info=True)
+
+ # 调焦、采集暗电流、采集白板、采集影像 都通过此函数
+ def run(self):
+ try:
+ self.qt_sender = self.sender().objectName()
+
+ if self.qt_sender == 'image_mode_focus_bt':
+ if camera.get_framerate() <= 10: # 调焦时控制帧率在20以内,以防帧率过高,界面卡死
+ if self.focus_count % 2 == 1:
+ self.image_mode_focus_bt.setText('停止调焦')
+ self.core_operation()
+ self.focus_count += 1
+
+ self.change_widget_background_color(self.image_mode_focus_bt, 'red')
+ elif self.focus_count % 2 == 0:
+ self.image_camera_operation.focus = False
+ self.image_mode_focus_bt.setText('调焦')
+ self.focus_count += 1
+ else:
+ self.x = MessageBox('调焦时帧率最大为10!')
+ elif self.qt_sender == 'image_mode_exposureTime_bt':
+ self.state = 1
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_exposureTime_bt, 'red')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ if self.state == 0:
+
+ self.x = MessageBox('请先曝光!')
+ elif self.state == 1: # 正常采集暗电流
+ self.state = 4
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_dc_bt, 'red')
+ elif self.state == 4 or self.state == 9:
+ self.x = MessageBox('已经执行过暗电流!')
+ elif self.qt_sender == 'image_mode_wb_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光 + 暗电流!')
+ elif self.state == 1:
+ self.x = MessageBox('请先暗电流!')
+ elif self.state == 4: # 正常采集白板
+ self.state = 9
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_wb_bt, 'red')
+ elif self.state == 9: # 重新采集白板
+ self.state = 9
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_wb_bt, 'red')
+ elif self.qt_sender == 'image_mode_record_bt':
+ if self.record_count % 2 == 1:
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ elif self.state == 1: # 正常采集DN值影像
+ if type(self.image_camera_operation.image_dc) is np.ndarray and type(
+ self.image_camera_operation.image_wb) is np.ndarray: # 这个判断是为了在手动改变曝光时间的情况下,强制让用于重新采集暗电流和白板
+ self.x = MessageBox('请重新暗电流+白板!')
+ else:
+ self.record_count += 1
+ self.plot_frame_count_multiple = 1 # 每次点击采集按钮都将此变量设置为1,用于正常边采集影像边在界面中显示影像
+
+ self.image_mode_record_bt.setText('停止采集')
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_record_bt, 'red')
+ elif self.state == 4:
+ self.x = MessageBox('请先白板!')
+ elif self.state == 9: # 正常采集反射率影像
+ self.record_count += 1
+ self.plot_frame_count_multiple = 1 # 每次点击采集按钮都将此变量设置为1,用于正常边采集影像边在界面中显示影像
+
+ self.image_mode_record_bt.setText('停止采集')
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_record_bt, 'red')
+ elif self.record_count % 2 == 0:
+ self.image_camera_operation.record = False
+ self.image_mode_record_bt.setText('采集')
+ self.record_count += 1
+ elif self.qt_sender == 'save_bt':
+ worker = Worker(self.savedata)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+
+ self.threadpool.start(worker)
+
+ self.change_widget_background_color(self.save_bt, 'red')
+ except Exception:
+ traceback.print_exc()
+
+ # 改变按钮三态中普通态的背景颜色
+ def change_widget_background_color(self, qt_widget, color):
+ pattern = re.compile('background-color(.*)(normal\*/)')
+ old_style_sheet = qt_widget.styleSheet()
+
+ if color == 'red':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'green':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'gray':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(225 , 225 , 225);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+
+ def core_operation(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.image_camera_operation.start_AcquireData, camera, self.qt_sender, self.plot_signal)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ self.disable_bt(True)
+
+ def disable_bt(self, bool):
+ # 两个if判断存在的原因:调焦/停止调焦(采集/停止采集)使用同一个按钮,所以不能将其设置为不可用
+ if self.qt_sender !='image_mode_focus_bt':
+ self.image_mode_focus_bt.setDisabled(bool)
+ if self.qt_sender != 'image_mode_record_bt':
+ self.image_mode_record_bt.setDisabled(bool)
+
+ self.image_mode_exposureTime_bt.setDisabled(bool)
+ self.image_mode_dc_bt.setDisabled(bool)
+ self.image_mode_wb_bt.setDisabled(bool)
+ self.save_bt.setDisabled(bool)
+ self.arcus_left_bt.setDisabled(bool)
+ self.arcus_right_bt.setDisabled(bool)
+
+ self.exposure_time_le.setDisabled(bool)
+ self.framerate_le.setDisabled(bool)
+ self.arcus_speed_le.setDisabled(bool)
+ self.framenumber_le.setDisabled(bool)
+ self.filename_le.setDisabled(bool)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if traceback_info[1].status == 1: # 在ximea的API中代表"Invalid handle":相机断开连接
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.error('自动曝光失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.error('调焦失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.error('采集暗电流失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.logger.error('采集白板失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.error('采集影像失败:相机断开连接!\n%s', traceback_info[2])
+ elif traceback_info[1].status == 56: # 在ximea的API中代表"No Devices Found":在执行cam.open_device()时,无相机打开
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.error('自动曝光失败:无相机可供打开!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.error('调焦失败:无相机可供打开!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.error('采集暗电流失败:无相机可供打开\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.logger.error('采集白板失败:无相机可供打开\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.error('采集影像失败:无相机可供打开\n%s', traceback_info[2])
+ elif traceback_info[1].status == 12: # 在ximea的API中代表"Not supported":当相机正在采集数据时,执行代码cam.set_imgdataformat('XI_RAW16')
+ pass
+ elif traceback_info[1].status == 41: # 在ximea的API中代表"Acquisition already started":相机已经开始采集数据
+ pass
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'save_bt':
+ self.logger.error('保存影像失败--影像名不正确!\n%s', traceback_info[2])
+ # QMessageBox.information(self, '提示', '请输入正确的影像名!', QMessageBox.Yes)
+
+ self.x = MessageBox('请输入正确的影像名!')
+ elif traceback_info[0] == FileNotFoundError:
+ if self.qt_sender == 'save_bt':
+ self.logger.error('保存影像失败--没有采集影像!\n%s', traceback_info[2])
+ # QMessageBox.information(self, '提示', '请输入正确的影像名!', QMessageBox.Yes)
+
+ self.x = MessageBox('请先采集影像!')
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ print('operate_failed函数运行成功!')
+
+ def operate_success(self):
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.info('自动曝光成功----------------!')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.info('调焦成功!')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.image_mode_dc_bt.setText('暗 电 流✔')
+
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'image_mode_wb_bt':
+ self.image_mode_wb_bt.setText('白 板✔')
+
+ self.logger.info('采集白板成功!')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.info('采集影像成功!')
+
+ self.image_mode_record_bt.setText('采集')
+ self.record_count += 1
+ elif self.qt_sender == 'save_bt':
+ self.logger.info('保存影像成功!')
+
+ self.disable_bt(False)
+
+ # 当操作成功后,所有按钮都变为初始颜色:灰色
+ self.change_widget_background_color(self.image_mode_exposureTime_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_focus_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_dc_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_wb_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_record_bt, 'gray')
+ self.change_widget_background_color(self.save_bt, 'gray')
+
+ # 保存影像数据
+ def savedata(self):
+ self.disable_bt(True) # 因为保存影像所需时间较多,所以需要将此行代码放在最前面
+
+ # 保存路径
+ # filename = "%s%s%s" % (re.sub('/', '\\\\', self.config_file_object.image_dir), '\\', self.config_file_object.default_image_name)
+ filename, file_number = return_file_path([], self.config_file_object.image_dir,
+ self.config_file_object.default_image_name)
+
+ # 保存影像和头文件
+ imagefile = "%s%s%s" % (os.getcwd(), '\\', 'corning410_test')
+ shutil.copyfile(imagefile, filename)
+ shutil.copyfile("%s%s" % (imagefile, '.hdr'), "%s%s" % (filename, '.hdr'))
+
+ self.file_number_label.setText(str(file_number))
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和self.config对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+ try:
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ self.exposure_time_le.setText(str(result[0]))
+
+ # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为self.config.exposure_time的旧值
+ self.config_file_object.exposure_time = result[0]
+ self.config_file_object.gain = result[1]
+
+ try:
+ # 将自动曝光值保存到配置文件中
+ self.config_file_object.image_signal.emit({'exposure_time': result[0], 'gain': result[1]})
+ except:
+ traceback.print_exc()
+
+
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if result[2] == 1:
+ # QMessageBox.information(self, '曝光提示', '光线不足,曝光时间已设置为最大!', QMessageBox.Yes)
+
+ self.x = MessageBox('光线不足,曝光时间已设置为最大!')
+ self.image_camera_operation.autoexposure_feedback = 0
+ except:
+ traceback.print_exc()
+
+ def closeEvent(self, a0: QtGui.QCloseEvent):
+ camera.stop_acquisition()
+
+
+# 光谱窗口
+class SpectralWindow(QDialog, Ui_spectral_Window_phone):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ progress_bar_and_plot_spectral_signal = pyqtSignal(int)
+
+ def __init__(self, parent=None):
+ super(SpectralWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:此行代码必须放在show()函数之前
+
+ # 数据采集保存类,采集数据并将数据保存在此类中,数据采集和界面分离
+
+ # 配置文件读取和写入类,配置文件读写和界面分离
+ # 1、采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取
+ # 2、并保存在此类中
+ self.config_file_object = ConfigFile()
+
+ self.spectral_camera_operation = SpectralCameraOperation(self.config_file_object)
+
+ self.progress_bar_and_plot_spectral_signal.connect(self.plot_save_spectral)
+
+ self.state = 0 # 光谱仪操作状态:曝光=1;暗电流=3;白板=5 → 所以只有state==9时才能开始采集光谱
+ self.dc_time = time.time() # 用于暗电流计时(从采集成功后那一刻开始)
+ self.dc_timer = QTimer()
+ self.dc_timer.timeout.connect(self.dc_timer_slot)
+
+ self.wb_time = time.time() # 用于暗电流计时(从采集成功后那一刻开始)
+ self.wb_timer = QTimer()
+ self.wb_timer.timeout.connect(self.wb_timer_slot)
+
+ self.progressBar.setMaximum(self.config_file_object.spectral_number)
+ self.progressBar.setValue(0)
+
+ # log
+ self.logger = logging.getLogger('root.spectral')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//spectral_operate.log'):
+ with open(self.config_file_object.log_dir + '//spectral_operate.log', 'w') as f:
+ pass
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ spectral_operate_file_handler = logging.FileHandler(self.config_file_object.log_dir + "//spectral_operate.log") # 输出到文件
+ spectral_operate_file_handler.setLevel(logging.INFO)
+ spectral_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(spectral_operate_file_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.serial_signal.connect(self.temperature)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化值
+ self.filename_le.setText(self.config_file_object.default_spectral_name)
+ self.spectral_number_le.setText(str(self.config_file_object.spectral_number))
+ self.framenumber_average_le.setText(str(self.config_file_object.framenumber_average))
+ self.autoexposure_le.setText(str(self.config_file_object.exposure_time_spectral))
+
+ # 显示光谱和align
+ # self.spectralFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
+ self.spectralFigure = QtSpectralViewer(ylabel_and_range='reflectance')
+ self.spe_glo.addWidget(self.spectralFigure)
+
+ #操作光谱仪
+ # self.dc_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ self.spectral_mode_autoexposure_bt.clicked.connect(self.run)
+ self.spectral_mode_wb_bt.clicked.connect(self.run) # 曝光 + 采集白板
+ self.spectral_mode_dc_bt.clicked.connect(self.run)
+ self.spectral_mode_record_bt.clicked.connect(self.run)
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filename_le.editingFinished.connect(self.onchange)
+ my_regex1 = QRegExp("[a-zA-Z0-9]*")
+ my_validator1 = QRegExpValidator(my_regex1, self.filename_le)
+ self.filename_le.setValidator(my_validator1)
+
+ self.autoexposure_le.editingFinished.connect(self.onchange)
+ my_regex2 = QRegExp("[0-9]*")
+ my_validator2 = QRegExpValidator(my_regex2, self.autoexposure_le)
+ self.autoexposure_le.setValidator(my_validator2)
+
+ self.spectral_number_le.editingFinished.connect(self.onchange)
+ self.framenumber_average_le.editingFinished.connect(self.onchange)
+ my_regex3 = QRegExp("[0-9]*")
+ my_validator3 = QRegExpValidator(my_regex2, self.autoexposure_le)
+ self.spectral_number_le.setValidator(my_validator2)
+ self.framenumber_average_le.setValidator(my_validator2)
+
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ # print('相机打开成功!')
+
+ self.camera_status_label.setText('光谱仪:正常')
+ self.change_widget_background_color(self.camera_status_label, 'green')
+ elif imager_status == 1001:
+ print('相机打开时出现不是ximea错误的未知错误!')
+ elif imager_status == 1:
+ # print('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ self.camera_status_label.setText('光谱仪:断开连接')
+ self.change_widget_background_color(self.camera_status_label, 'red')
+
+ self.setEnabled(False)
+ self.close()
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ print('没有检测到光谱仪!')
+ elif imager_status == 103:
+ pass
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ try:
+ if self.sender().objectName() == 'autoexposure_le':
+ self.state = 1 # 手动改变曝光时间后,需要强制让用户重新采集暗电流和白板
+
+ exposure_time_tmp = int(self.autoexposure_le.text())
+
+ self.config_file_object.spectral_signal.emit({'exposure_time_spectral': exposure_time_tmp})
+
+ camera.set_exposure(exposure_time_tmp) # 曝光时间单位为微秒,1s共有1000000微秒
+ # camera.set_gain(int(float(self.config_file_object.gain))) # int('0.0')会报错,int(float('0.0'))不会报错
+
+ self.logger.info('手动改变曝光时间!')
+ elif self.sender().objectName() == 'framenumber_average_le':
+ framenumber_average_tmp = int(self.framenumber_average_le.text())
+
+ self.config_file_object.spectral_signal.emit({'framenumber_average': framenumber_average_tmp})
+
+ self.spectral_camera_operation.create_image_container(framenumber_average_tmp)
+
+ self.logger.info('手动改变每条光谱的平均帧数!')
+ elif self.sender().objectName() == 'spectral_number_le':
+ spectral_number_tmp = int(self.spectral_number_le.text())
+
+ self.config_file_object.spectral_signal.emit({'spectral_number': spectral_number_tmp})
+
+ self.progressBar.setMaximum(spectral_number_tmp)
+ self.progressBar.setValue(0)
+
+ self.spectral_camera_operation.create_spectral_container(spectral_number_tmp)
+
+ self.logger.info('手动改变保存的光谱数!')
+ elif self.sender().objectName() == 'filename_le':
+ filename = self.filename_le.text()
+
+ if filename != '':
+ self.config_file_object.spectral_signal.emit({'default_spectral_name': filename})
+
+ self.logger.info('改变光谱文件名!')
+ except:
+ traceback.print_exc()
+
+ def plot_save_spectral(self, x):
+ try:
+ self.progressBar.setValue(x)
+
+ # 画出光谱
+ if self.data_type_comboBox.currentText() == 'DN':
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn[:, 0], self.spectral_camera_operation.spectral_dn[:, x])
+ if self.data_type_comboBox.currentText() == 'Rad':
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn[:, 0], self.spectral_camera_operation.spectral_rad[:, x])
+ if self.data_type_comboBox.currentText() == 'Ref':
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn[:, 0], self.spectral_camera_operation.spectral_ref[:, x])
+
+ # 保存光谱
+ filename_dn, file_number_dn = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_dn', model='spectral')
+ filename_rad, file_number_rad = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_rad', model='spectral')
+ filename_ref, file_number_ref = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_ref', model='spectral')
+ # print(filename_ref)
+
+ header_dn = self.get_spectral_metadata('DN')
+ header_rad = self.get_spectral_metadata('RAD')
+ header_ref = self.get_spectral_metadata('REF')
+
+ np.savetxt(filename_dn, self.spectral_camera_operation.spectral_dn[:, [0, x]], fmt='%f', header=header_dn)
+ np.savetxt(filename_rad, self.spectral_camera_operation.spectral_rad[:, [0, x]], fmt='%f', header=header_rad)
+ np.savetxt(filename_ref, self.spectral_camera_operation.spectral_ref[:, [0, x]], fmt='%f', header=header_ref)
+
+ self.file_number_label.setText(str(file_number_dn))
+ except:
+ traceback.print_exc()
+
+ def get_spectral_metadata(self, data_type_str):
+
+ record_time = "%s%s" % ('RecordTime = ', str(datetime.datetime.now()))
+ SN = 'SN = 0001'
+ exposure_time = "%s%s" % ('ExposureTime = ', str(camera.get_exposure()))
+ data_type = "%s%s" % ('DataType = ', data_type_str)
+
+ header = '%s%s%s%s%s%s%s' % (record_time, '\n', SN, '\n', exposure_time, '\n', data_type)
+ return header
+
+ def temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+ except:
+ traceback.print_exc()
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def dc_timer_slot(self):
+ now = time.time()
+ x = now - self.dc_time
+ self.dc_timer_label.setText(str(int(x)) + 's')
+
+ def wb_timer_slot(self):
+ now = time.time()
+ x = now - self.wb_time
+ self.wb_timer_label.setText(str(int(x)) + 's')
+
+ def run(self):
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ print('SpectralWindow采集曝光')
+
+ self.logger.info('曝光...')
+
+ self.state = 1
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_autoexposure_bt, 'red')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ try:
+ if self.state == 0:
+ # QMessageBox.information(self, '提示', '请先曝光!', QMessageBox.Yes)
+ self.x = MessageBox('请先曝光!')
+ elif self.state == 1 or self.state == 4 or self.state == 9:
+ self.logger.info('采集暗电流...')
+ self.state = 4
+
+ # 暗电流计时
+ self.dc_time = time.time()
+ self.dc_timer.start(2000)
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_dc_bt, 'red')
+ except:
+ traceback.print_exc()
+ elif self.qt_sender == 'spectral_mode_wb_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光+暗电流!')
+ elif self.state == 1:
+ self.x = MessageBox('请先采集暗电流!')
+ elif self.state == 4 or self.state == 9:
+ self.logger.info('采集白板...')
+ self.state = 9
+
+ # 白板计时
+ self.wb_time = time.time()
+ self.wb_timer.start(2000)
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_wb_bt, 'red')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光+暗电流+白板')
+ elif self.state == 1:
+ # QMessageBox.information(self, '提示', '请先采集暗电流!', QMessageBox.Yes)
+ self.x = MessageBox('请先暗电流+白板')
+ elif self.state == 4:
+ # QMessageBox.information(self, '提示', '请先采集暗电流!', QMessageBox.Yes)
+ self.x = MessageBox('请先白板')
+ elif self.state == 9:
+ self.logger.info('采集光谱...')
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_record_bt, 'red')
+
+ # 改变按钮三态中普通态的背景颜色
+ def change_widget_background_color(self, qt_widget, color):
+ pattern = re.compile('background-color(.*)(normal\*/)')
+ old_style_sheet = qt_widget.styleSheet()
+
+ if color == 'red':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'green':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'gray':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(225 , 225 , 225);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和self.config_file_object对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ self.autoexposure_le.setText(str(result[0]))
+
+ # # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为self.config_file_object.exposure_time的旧值
+ # self.config_file_object.exposure_time = result[0]
+ # self.config_file_object.gain = result[1]
+
+ def core_operation(self):
+ worker = Worker(self.spectral_camera_operation.start_AcquireData, camera, self.qt_sender,
+ self.progress_bar_and_plot_spectral_signal)
+ worker.signals.finished.connect(self.operate_success)
+ worker.signals.error.connect(self.operate_failed)
+
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ self.disable_bt_le(True)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.logger.error('曝光/白板失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.logger.error('align 失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.logger.error('采集暗电流失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.error('采集光谱失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.error('保存光谱失败!\n%s', traceback_info[2])
+ # QMessageBox.information(self, '提示', '请输入正确的光谱名!', QMessageBox.Yes)
+
+ self.x = MessageBox('请输入正确的光谱名!')
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ self.logger.info('曝光成功!')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'spectral_mode_wb_bt':
+ self.logger.info('采集白板成功!')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.logger.info('align successfully!')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.info('采集光谱成功!')
+
+ self.disable_bt_le(False)
+
+ # 当操作成功后,所有按钮都变为初始颜色:灰色
+ self.change_widget_background_color(self.spectral_mode_autoexposure_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_dc_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_wb_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_record_bt, 'gray')
+
+ def disable_bt_le(self, bool):
+ self.spectral_mode_autoexposure_bt.setDisabled(bool)
+ self.spectral_mode_dc_bt.setDisabled(bool)
+ self.spectral_mode_wb_bt.setDisabled(bool)
+ self.spectral_mode_record_bt.setDisabled(bool)
+
+ self.spectral_number_le.setDisabled(bool)
+ self.framenumber_average_le.setDisabled(bool)
+ self.autoexposure_le.setDisabled(bool)
+ self.filename_le.setDisabled(bool)
+
+ def closeEvent(self, a0: QtGui.QCloseEvent):
+ camera.stop_acquisition()
+
+
+# 影像模式类:相关的函数和变量
+class CameraOperation(object):
+ def __init__(self, config_file_object):
+ self.config_file_object = config_file_object
+
+ # self.startRow = 339
+ # self.endRow = 639
+ # self.startColumn = 285
+ # self.endColumn = 1649
+
+ # 转辐亮度
+ self.rad_or_not = False
+ if self.config_file_object.binning == 1:
+ self.img_gain = get_resource_path('./data/lens_bin1_gain_SN0073')
+ self.cal_it = 7266
+ elif self.config_file_object.binning == 2:
+ self.img_gain = get_resource_path('./data/lens_bin2_gain_SN0073')
+ self.cal_it = 1621
+ _, _, self.gain = ImageReaderWriter.read_img(self.img_gain)
+
+ self.gain = self.gain.astype(np.float32)
+ self.target_it = None
+ self.gain_scale = None
+
+ #
+ self.arcus_reverse_while_record = False
+ self.record_DN = False
+
+ # 开始采集数据
+ self.image_dc = None # 随便给个初始值,此变量用于存储采集到的暗电流影像
+ self.image_wb = None # 随便给个初始值,此变量用于存储采集到的白板影像
+ self.focus = True # 用于停止调焦
+ self.record = True # 用于停止采集
+ self.img_datatype = 12 # 在头文件中确定影像数据类型
+
+ self.autoexposure_feedback = 0 # 指示:自动曝光所得到的shutter值是否为最大;如果为最大→值设置为1
+
+ # 创建rgb数据,用于在界面中显示
+ self.create_rgb()
+
+ def create_rgb(self):
+ self.rgb = np.ones((3, int(self.config_file_object.frame_number), self.config_file_object.end_column - self.config_file_object.start_column))
+
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposure_gain_framerate(self, cam):
+ # settings,cam.set_param("exposure",10000)
+ cam.set_framerate(self.config_file_object.framerate)
+ cam.set_exposure(self.config_file_object.exposure_time) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(self.config_file_object.gain) #int('0.0')会报错,int(float('0.0'))不会报错
+
+ print('set_exposure_gain_framerate运行成功')
+
+ def start_AcquireData(self, cam, qt_sender, plot_signal=None): # qt_sender是指qt窗口中事件的发生者
+ '''
+ :param cam: 实例化的相机句柄
+ :param qt_sender: 调用本方法时,点击的界面上的按钮名;
+ :param plot_signal:
+ :return:
+ '''
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ # 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+ # 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype('= 4090:
+ cam.set_exposure(int(0.9 * cam.get_exposure()))
+
+ cam.start_acquisition()
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ image_raw_numpy = img.get_image_data_numpy()
+
+ # 如果因为光线不足曝光值达到了最大,就将曝光反馈变量设置为1
+ if cam.get_exposure() > int(1 / self.config_file_object.framerate * 10**6):
+ cam.set_exposure(int(1 / self.config_file_object.framerate * 10**6))
+ self.autoexposure_feedback = 1
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+ # 计算gain
+ self.target_it = cam.get_exposure()
+ self.gain_scale = self.cal_it / self.target_it
+ self.gain = self.gain * self.gain_scale
+
+ print('start_AcquireData--自动曝光运行结束')
+
+ # 如果点击“调焦”按钮
+ if qt_sender == 'image_mode_focus_bt':
+ # cls.set_exposureTime(cam)
+
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not self.focus:
+ self.focus = True
+
+ cam.start_acquisition()
+
+ while self.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ self.image_container = image_raw_numpy[self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+
+ if plot_signal is not None:
+ plot_signal.emit()
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'image_mode_dc_bt':
+ framenumber = 10
+ image_container = np.empty((
+ self.config_file_object.end_row - self.config_file_object.start_row, framenumber,
+ self.config_file_object.end_column - self.config_file_object.start_column))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[self.config_file_object.start_row:self.config_file_object.end_row, self.config_file_object.start_column:self.config_file_object.end_column]
+
+ image_container = image_container.mean(axis=1)
+
+ self.image_dc = image_container
+
+ # 如果点击“白板”按钮,采集并保存白板影像到image_wb
+ if qt_sender == 'image_mode_wb_bt':
+ framenumber = 10
+ image_container = np.empty((
+ self.config_file_object.end_row - self.config_file_object.start_row, framenumber,
+ self.config_file_object.end_column - self.config_file_object.start_column))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[
+ self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+
+ image_container = image_container.mean(axis=1)
+
+ # 扣除暗电流的白板
+ self.image_wb = image_container - self.image_dc
+
+ # 如果点击“采集”按钮,自动去除暗电流,并且转化成反射率
+ if qt_sender == 'image_mode_record_bt':
+ frameCount = 1 # 统计采集的帧数,用于停止采集使用
+
+ # 当停止采集后,再次开始采集需要将cls.record的值从False变为True
+ if not self.record:
+ self.record = True
+
+ # 启动马达
+ self.arcus_start()
+
+ # 开始采集数据 并且 将数据写入到硬盘中
+ cam.start_acquisition()
+ with open('corning410_test', 'wb') as f:
+
+ print('Starting data acquisition...')
+ startTime = datetime.datetime.now()
+
+ while self.record:
+ cam.get_image(img) # get data and pass them from camera to img
+ # image_raw_numpy.dtype -> dtype('
+
+ enter_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+ -
+
+
+ true
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
+ 正在打开相机...
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 光谱模式
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 影像模式
+
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v26/ui/image_Window_phone.py b/record_system_v26/ui/image_Window_phone.py
new file mode 100644
index 0000000..727ee3e
--- /dev/null
+++ b/record_system_v26/ui/image_Window_phone.py
@@ -0,0 +1,830 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window_phone.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window_phone(object):
+ def setupUi(self, image_Window_phone):
+ image_Window_phone.setObjectName("image_Window_phone")
+ image_Window_phone.setEnabled(True)
+ image_Window_phone.resize(518, 1174)
+ image_Window_phone.setMouseTracking(False)
+ image_Window_phone.setAutoFillBackground(False)
+ image_Window_phone.setSizeGripEnabled(False)
+ image_Window_phone.setModal(False)
+ self.gridLayout_6 = QtWidgets.QGridLayout(image_Window_phone)
+ self.gridLayout_6.setObjectName("gridLayout_6")
+ self.splitter = QtWidgets.QSplitter(image_Window_phone)
+ self.splitter.setOrientation(QtCore.Qt.Vertical)
+ self.splitter.setObjectName("splitter")
+ self.frame_2 = QtWidgets.QFrame(self.splitter)
+ self.frame_2.setFrameShape(QtWidgets.QFrame.Box)
+ self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_2.setObjectName("frame_2")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_2)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.gridLayout_2.addLayout(self.image_glo, 0, 0, 1, 1)
+ self.frame = QtWidgets.QFrame(self.splitter)
+ self.frame.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame.setFrameShape(QtWidgets.QFrame.Box)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.gridLayout = QtWidgets.QGridLayout(self.frame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.gridLayout.addLayout(self.focus_glo, 0, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.splitter, 0, 0, 1, 1)
+ self.frame_3 = QtWidgets.QFrame(image_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
+ self.frame_3.setSizePolicy(sizePolicy)
+ self.frame_3.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.frame_3)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.frame_7 = QtWidgets.QFrame(self.frame_3)
+ self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_7.setObjectName("frame_7")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_7)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.verticalLayout = QtWidgets.QVBoxLayout()
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.image_mode_exposureTime_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_exposureTime_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_exposureTime_bt.setSizePolicy(sizePolicy)
+ self.image_mode_exposureTime_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_exposureTime_bt.setFont(font)
+ self.image_mode_exposureTime_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_exposureTime_bt.setAutoDefault(False)
+ self.image_mode_exposureTime_bt.setObjectName("image_mode_exposureTime_bt")
+ self.verticalLayout.addWidget(self.image_mode_exposureTime_bt)
+ self.image_mode_focus_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_focus_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_focus_bt.setSizePolicy(sizePolicy)
+ self.image_mode_focus_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_focus_bt.setFont(font)
+ self.image_mode_focus_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_focus_bt.setAutoDefault(False)
+ self.image_mode_focus_bt.setObjectName("image_mode_focus_bt")
+ self.verticalLayout.addWidget(self.image_mode_focus_bt)
+ self.image_mode_dc_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_dc_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_dc_bt.setSizePolicy(sizePolicy)
+ self.image_mode_dc_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_dc_bt.setFont(font)
+ self.image_mode_dc_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_dc_bt.setAutoDefault(False)
+ self.image_mode_dc_bt.setObjectName("image_mode_dc_bt")
+ self.verticalLayout.addWidget(self.image_mode_dc_bt)
+ self.image_mode_wb_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_wb_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_wb_bt.setSizePolicy(sizePolicy)
+ self.image_mode_wb_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_wb_bt.setFont(font)
+ self.image_mode_wb_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_wb_bt.setAutoDefault(False)
+ self.image_mode_wb_bt.setObjectName("image_mode_wb_bt")
+ self.verticalLayout.addWidget(self.image_mode_wb_bt)
+ self.image_mode_record_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_record_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_record_bt.setSizePolicy(sizePolicy)
+ self.image_mode_record_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_record_bt.setFont(font)
+ self.image_mode_record_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_record_bt.setAutoDefault(False)
+ self.image_mode_record_bt.setObjectName("image_mode_record_bt")
+ self.verticalLayout.addWidget(self.image_mode_record_bt)
+ self.save_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.save_bt.sizePolicy().hasHeightForWidth())
+ self.save_bt.setSizePolicy(sizePolicy)
+ self.save_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.save_bt.setFont(font)
+ self.save_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.save_bt.setAutoDefault(False)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout.addWidget(self.save_bt)
+ self.gridLayout_4.addLayout(self.verticalLayout, 0, 0, 1, 1)
+ self.gridLayout_5.addWidget(self.frame_7, 0, 0, 1, 1)
+ self.frame_6 = QtWidgets.QFrame(self.frame_3)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_6)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setObjectName("gridLayout_3")
+ self.frame_8 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_8.sizePolicy().hasHeightForWidth())
+ self.frame_8.setSizePolicy(sizePolicy)
+ self.frame_8.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_8.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_8.setLineWidth(0)
+ self.frame_8.setObjectName("frame_8")
+ self.gridLayout_3.addWidget(self.frame_8, 3, 0, 1, 1)
+ self.frame_10 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_10.sizePolicy().hasHeightForWidth())
+ self.frame_10.setSizePolicy(sizePolicy)
+ self.frame_10.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_10.setObjectName("frame_10")
+ self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_10)
+ self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_8.setSpacing(0)
+ self.gridLayout_8.setObjectName("gridLayout_8")
+ self.label_2 = QtWidgets.QLabel(self.frame_10)
+ self.label_2.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_2.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout_8.addWidget(self.label_2, 0, 0, 1, 1)
+ self.framenumber_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framenumber_le.sizePolicy().hasHeightForWidth())
+ self.framenumber_le.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.framenumber_le.setFont(font)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.gridLayout_8.addWidget(self.framenumber_le, 0, 1, 1, 1)
+ self.gridLayout_3.addWidget(self.frame_10, 4, 0, 1, 1)
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.label_3 = QtWidgets.QLabel(self.frame_6)
+ self.label_3.setMinimumSize(QtCore.QSize(110, 0))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(20)
+ self.label_3.setFont(font)
+ self.label_3.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.horizontalLayout_3.addWidget(self.label_3)
+ self.framerate_le = QtWidgets.QLineEdit(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framerate_le.sizePolicy().hasHeightForWidth())
+ self.framerate_le.setSizePolicy(sizePolicy)
+ self.framerate_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.framerate_le.setFont(font)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.horizontalLayout_3.addWidget(self.framerate_le)
+ self.gridLayout_3.addLayout(self.horizontalLayout_3, 1, 0, 1, 1)
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ self.label_5 = QtWidgets.QLabel(self.frame_6)
+ self.label_5.setMinimumSize(QtCore.QSize(110, 0))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(20)
+ self.label_5.setFont(font)
+ self.label_5.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_5.setObjectName("label_5")
+ self.horizontalLayout_4.addWidget(self.label_5)
+ self.exposure_time_le = QtWidgets.QLineEdit(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.exposure_time_le.sizePolicy().hasHeightForWidth())
+ self.exposure_time_le.setSizePolicy(sizePolicy)
+ self.exposure_time_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.exposure_time_le.setFont(font)
+ self.exposure_time_le.setObjectName("exposure_time_le")
+ self.horizontalLayout_4.addWidget(self.exposure_time_le)
+ self.gridLayout_3.addLayout(self.horizontalLayout_4, 0, 0, 1, 1)
+ self.frame_5 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth())
+ self.frame_5.setSizePolicy(sizePolicy)
+ self.frame_5.setMinimumSize(QtCore.QSize(160, 0))
+ self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_5.setObjectName("frame_5")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_5)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.label_7 = QtWidgets.QLabel(self.frame_5)
+ self.label_7.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_7.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_7.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_7.setObjectName("label_7")
+ self.horizontalLayout_2.addWidget(self.label_7)
+ self.arcus_left_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_left_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_left_bt.setSizePolicy(sizePolicy)
+ self.arcus_left_bt.setMinimumSize(QtCore.QSize(50, 0))
+ self.arcus_left_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_left_bt.setFont(font)
+ self.arcus_left_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_left_bt.setAutoDefault(False)
+ self.arcus_left_bt.setObjectName("arcus_left_bt")
+ self.horizontalLayout_2.addWidget(self.arcus_left_bt)
+ self.arcus_speed_le = QtWidgets.QLineEdit(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_speed_le.sizePolicy().hasHeightForWidth())
+ self.arcus_speed_le.setSizePolicy(sizePolicy)
+ self.arcus_speed_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.arcus_speed_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.arcus_speed_le.setFont(font)
+ self.arcus_speed_le.setObjectName("arcus_speed_le")
+ self.horizontalLayout_2.addWidget(self.arcus_speed_le)
+ self.arcus_right_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_right_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_right_bt.setSizePolicy(sizePolicy)
+ self.arcus_right_bt.setMinimumSize(QtCore.QSize(50, 0))
+ self.arcus_right_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_right_bt.setFont(font)
+ self.arcus_right_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_right_bt.setAutoDefault(False)
+ self.arcus_right_bt.setObjectName("arcus_right_bt")
+ self.horizontalLayout_2.addWidget(self.arcus_right_bt)
+ self.gridLayout_3.addWidget(self.frame_5, 2, 0, 1, 1)
+ self.frame_9 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_9.sizePolicy().hasHeightForWidth())
+ self.frame_9.setSizePolicy(sizePolicy)
+ self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_9.setLineWidth(0)
+ self.frame_9.setObjectName("frame_9")
+ self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_9)
+ self.gridLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_7.setSpacing(0)
+ self.gridLayout_7.setObjectName("gridLayout_7")
+ self.filename_le = QtWidgets.QLineEdit(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.filename_le.sizePolicy().hasHeightForWidth())
+ self.filename_le.setSizePolicy(sizePolicy)
+ self.filename_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.filename_le.setFont(font)
+ self.filename_le.setObjectName("filename_le")
+ self.gridLayout_7.addWidget(self.filename_le, 0, 1, 1, 1)
+ self.file_number_label = QtWidgets.QLabel(self.frame_9)
+ self.file_number_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.file_number_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.file_number_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.file_number_label.setObjectName("file_number_label")
+ self.gridLayout_7.addWidget(self.file_number_label, 0, 2, 1, 1)
+ self.label_6 = QtWidgets.QLabel(self.frame_9)
+ self.label_6.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_6.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_6.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_6.setObjectName("label_6")
+ self.gridLayout_7.addWidget(self.label_6, 0, 0, 1, 1)
+ self.gridLayout_3.addWidget(self.frame_9, 6, 0, 1, 1)
+ self.gridLayout_5.addWidget(self.frame_6, 0, 1, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_3, 1, 0, 1, 1)
+ self.frame_4 = QtWidgets.QFrame(image_Window_phone)
+ self.frame_4.setMinimumSize(QtCore.QSize(0, 0))
+ self.frame_4.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_4.setObjectName("frame_4")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_4)
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ spacerItem = QtWidgets.QSpacerItem(233, 12, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.t_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.t_label.sizePolicy().hasHeightForWidth())
+ self.t_label.setSizePolicy(sizePolicy)
+ self.t_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.t_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.t_label.setObjectName("t_label")
+ self.horizontalLayout.addWidget(self.t_label)
+ self.hum_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.hum_label.sizePolicy().hasHeightForWidth())
+ self.hum_label.setSizePolicy(sizePolicy)
+ self.hum_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.hum_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.horizontalLayout.addWidget(self.hum_label)
+ self.camera_status_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.camera_status_label.sizePolicy().hasHeightForWidth())
+ self.camera_status_label.setSizePolicy(sizePolicy)
+ self.camera_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.camera_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camera_status_label.setObjectName("camera_status_label")
+ self.horizontalLayout.addWidget(self.camera_status_label)
+ self.arcus_status_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_status_label.sizePolicy().hasHeightForWidth())
+ self.arcus_status_label.setSizePolicy(sizePolicy)
+ self.arcus_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.arcus_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.arcus_status_label.setObjectName("arcus_status_label")
+ self.horizontalLayout.addWidget(self.arcus_status_label)
+ self.gridLayout_6.addWidget(self.frame_4, 2, 0, 1, 1)
+
+ self.retranslateUi(image_Window_phone)
+ QtCore.QMetaObject.connectSlotsByName(image_Window_phone)
+
+ def retranslateUi(self, image_Window_phone):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window_phone.setWindowTitle(_translate("image_Window_phone", "影像窗口"))
+ self.image_mode_exposureTime_bt.setText(_translate("image_Window_phone", "曝 光"))
+ self.image_mode_focus_bt.setText(_translate("image_Window_phone", "调 焦"))
+ self.image_mode_dc_bt.setText(_translate("image_Window_phone", "暗 电 流"))
+ self.image_mode_wb_bt.setText(_translate("image_Window_phone", "白 板"))
+ self.image_mode_record_bt.setText(_translate("image_Window_phone", "采 集"))
+ self.save_bt.setText(_translate("image_Window_phone", "保 存"))
+ self.label_2.setText(_translate("image_Window_phone", "帧 数"))
+ self.label_3.setText(_translate("image_Window_phone", "帧 率"))
+ self.label_5.setText(_translate("image_Window_phone", "积分时间"))
+ self.label_7.setText(_translate("image_Window_phone", "马 达"))
+ self.arcus_left_bt.setText(_translate("image_Window_phone", "<"))
+ self.arcus_right_bt.setText(_translate("image_Window_phone", ">"))
+ self.file_number_label.setText(_translate("image_Window_phone", "文件号"))
+ self.label_6.setText(_translate("image_Window_phone", "命 名"))
+ self.t_label.setText(_translate("image_Window_phone", "温度:无数据"))
+ self.hum_label.setText(_translate("image_Window_phone", "湿度:无数据"))
+ self.camera_status_label.setText(_translate("image_Window_phone", "光谱仪:连接失败"))
+ self.arcus_status_label.setText(_translate("image_Window_phone", "马达:连接失败!"))
diff --git a/record_system_v26/ui/image_Window_phone.ui b/record_system_v26/ui/image_Window_phone.ui
new file mode 100644
index 0000000..4c21f58
--- /dev/null
+++ b/record_system_v26/ui/image_Window_phone.ui
@@ -0,0 +1,1323 @@
+
+
+ image_Window_phone
+
+
+ true
+
+
+
+ 0
+ 0
+ 518
+ 1174
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 调 焦
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 白 板
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 保 存
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 42
+
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+ false
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 积分时间
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 160
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 马 达
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ <
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ >
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 命 名
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 233
+ 12
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 马达:连接失败!
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v26/ui/spectral_Window_phone.py b/record_system_v26/ui/spectral_Window_phone.py
new file mode 100644
index 0000000..1e6c05d
--- /dev/null
+++ b/record_system_v26/ui/spectral_Window_phone.py
@@ -0,0 +1,629 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window_phone.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window_phone(object):
+ def setupUi(self, spectral_Window_phone):
+ spectral_Window_phone.setObjectName("spectral_Window_phone")
+ spectral_Window_phone.resize(540, 1175)
+ self.gridLayout_6 = QtWidgets.QGridLayout(spectral_Window_phone)
+ self.gridLayout_6.setObjectName("gridLayout_6")
+ self.frame = QtWidgets.QFrame(spectral_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+ self.frame.setSizePolicy(sizePolicy)
+ self.frame.setMinimumSize(QtCore.QSize(0, 600))
+ self.frame.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.gridLayout = QtWidgets.QGridLayout(self.frame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.spe_glo = QtWidgets.QGridLayout()
+ self.spe_glo.setObjectName("spe_glo")
+ self.gridLayout.addLayout(self.spe_glo, 0, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame, 0, 0, 1, 1)
+ self.frame_2 = QtWidgets.QFrame(spectral_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
+ self.frame_2.setSizePolicy(sizePolicy)
+ self.frame_2.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_2.setObjectName("frame_2")
+ self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_2)
+ self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_8.setSpacing(0)
+ self.gridLayout_8.setObjectName("gridLayout_8")
+ self.frame_4 = QtWidgets.QFrame(self.frame_2)
+ self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_4.setObjectName("frame_4")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_4)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setSpacing(0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.spectral_mode_autoexposure_bt = QtWidgets.QPushButton(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_autoexposure_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_autoexposure_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_autoexposure_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_autoexposure_bt.setAutoDefault(False)
+ self.spectral_mode_autoexposure_bt.setObjectName("spectral_mode_autoexposure_bt")
+ self.gridLayout_4.addWidget(self.spectral_mode_autoexposure_bt, 0, 0, 1, 1)
+ self.autoexposure_le = QtWidgets.QLineEdit(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.autoexposure_le.sizePolicy().hasHeightForWidth())
+ self.autoexposure_le.setSizePolicy(sizePolicy)
+ self.autoexposure_le.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.autoexposure_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:40pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.autoexposure_le.setObjectName("autoexposure_le")
+ self.gridLayout_4.addWidget(self.autoexposure_le, 0, 1, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_4, 0, 0, 1, 1)
+ self.frame_6 = QtWidgets.QFrame(self.frame_2)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_6)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setSpacing(0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.dc_timer_label = QtWidgets.QLabel(self.frame_6)
+ self.dc_timer_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.dc_timer_label.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.dc_timer_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.dc_timer_label.setObjectName("dc_timer_label")
+ self.gridLayout_2.addWidget(self.dc_timer_label, 0, 1, 1, 1)
+ self.spectral_mode_dc_bt = QtWidgets.QPushButton(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_dc_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_dc_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_dc_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_dc_bt.setAutoDefault(False)
+ self.spectral_mode_dc_bt.setObjectName("spectral_mode_dc_bt")
+ self.gridLayout_2.addWidget(self.spectral_mode_dc_bt, 0, 0, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_6, 1, 0, 1, 1)
+ self.frame_7 = QtWidgets.QFrame(self.frame_2)
+ self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_7.setObjectName("frame_7")
+ self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_7)
+ self.gridLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_7.setSpacing(0)
+ self.gridLayout_7.setObjectName("gridLayout_7")
+ self.spectral_mode_wb_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_wb_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_wb_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_wb_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_wb_bt.setAutoDefault(False)
+ self.spectral_mode_wb_bt.setObjectName("spectral_mode_wb_bt")
+ self.gridLayout_7.addWidget(self.spectral_mode_wb_bt, 0, 0, 1, 1)
+ self.wb_timer_label = QtWidgets.QLabel(self.frame_7)
+ self.wb_timer_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.wb_timer_label.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.wb_timer_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.wb_timer_label.setObjectName("wb_timer_label")
+ self.gridLayout_7.addWidget(self.wb_timer_label, 0, 1, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_7, 2, 0, 1, 1)
+ self.frame_5 = QtWidgets.QFrame(self.frame_2)
+ self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_5.setObjectName("frame_5")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.frame_5)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setSpacing(0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.spectral_mode_record_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_record_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_record_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_record_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_record_bt.setAutoDefault(False)
+ self.spectral_mode_record_bt.setObjectName("spectral_mode_record_bt")
+ self.gridLayout_5.addWidget(self.spectral_mode_record_bt, 0, 0, 1, 1)
+ self.data_type_comboBox = QtWidgets.QComboBox(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.data_type_comboBox.sizePolicy().hasHeightForWidth())
+ self.data_type_comboBox.setSizePolicy(sizePolicy)
+ self.data_type_comboBox.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.data_type_comboBox.setStyleSheet("/*按钮普通态*/\n"
+"QComboBox\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}")
+ self.data_type_comboBox.setFrame(False)
+ self.data_type_comboBox.setObjectName("data_type_comboBox")
+ self.data_type_comboBox.addItem("")
+ self.data_type_comboBox.addItem("")
+ self.data_type_comboBox.addItem("")
+ self.gridLayout_5.addWidget(self.data_type_comboBox, 0, 1, 1, 1)
+ self.progressBar = QtWidgets.QProgressBar(self.frame_5)
+ self.progressBar.setProperty("value", 0)
+ self.progressBar.setTextVisible(False)
+ self.progressBar.setObjectName("progressBar")
+ self.gridLayout_5.addWidget(self.progressBar, 1, 0, 1, 2)
+ self.gridLayout_8.addWidget(self.frame_5, 3, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_2, 1, 0, 1, 1)
+ self.frame_3 = QtWidgets.QFrame(spectral_Window_phone)
+ self.frame_3.setMaximumSize(QtCore.QSize(16777215, 200))
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.gridLayout_10 = QtWidgets.QGridLayout(self.frame_3)
+ self.gridLayout_10.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_10.setSpacing(0)
+ self.gridLayout_10.setObjectName("gridLayout_10")
+ self.frame_9 = QtWidgets.QFrame(self.frame_3)
+ self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_9.setObjectName("frame_9")
+ self.gridLayout_9 = QtWidgets.QGridLayout(self.frame_9)
+ self.gridLayout_9.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_9.setSpacing(0)
+ self.gridLayout_9.setObjectName("gridLayout_9")
+ self.filename_le = QtWidgets.QLineEdit(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.filename_le.sizePolicy().hasHeightForWidth())
+ self.filename_le.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(61)
+ self.filename_le.setFont(font)
+ self.filename_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:61pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.filename_le.setObjectName("filename_le")
+ self.gridLayout_9.addWidget(self.filename_le, 0, 2, 1, 1)
+ self.label_2 = QtWidgets.QLabel(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
+ self.label_2.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.label_2.setFont(font)
+ self.label_2.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout_9.addWidget(self.label_2, 0, 1, 1, 1)
+ self.file_number_label = QtWidgets.QLabel(self.frame_9)
+ self.file_number_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.file_number_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.file_number_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.file_number_label.setObjectName("file_number_label")
+ self.gridLayout_9.addWidget(self.file_number_label, 0, 3, 1, 1)
+ self.frame_10 = QtWidgets.QFrame(self.frame_9)
+ self.frame_10.setMinimumSize(QtCore.QSize(200, 0))
+ self.frame_10.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.frame_10.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_10.setObjectName("frame_10")
+ self.gridLayout_11 = QtWidgets.QGridLayout(self.frame_10)
+ self.gridLayout_11.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_11.setSpacing(0)
+ self.gridLayout_11.setObjectName("gridLayout_11")
+ self.label_3 = QtWidgets.QLabel(self.frame_10)
+ self.label_3.setMinimumSize(QtCore.QSize(140, 0))
+ self.label_3.setMaximumSize(QtCore.QSize(110, 16777215))
+ self.label_3.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.gridLayout_11.addWidget(self.label_3, 0, 0, 1, 1)
+ self.label_4 = QtWidgets.QLabel(self.frame_10)
+ self.label_4.setMinimumSize(QtCore.QSize(140, 0))
+ self.label_4.setMaximumSize(QtCore.QSize(110, 16777215))
+ self.label_4.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_4.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_4.setObjectName("label_4")
+ self.gridLayout_11.addWidget(self.label_4, 1, 0, 1, 1)
+ self.spectral_number_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_number_le.sizePolicy().hasHeightForWidth())
+ self.spectral_number_le.setSizePolicy(sizePolicy)
+ self.spectral_number_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.spectral_number_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.spectral_number_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.spectral_number_le.setObjectName("spectral_number_le")
+ self.gridLayout_11.addWidget(self.spectral_number_le, 1, 2, 1, 1)
+ self.framenumber_average_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framenumber_average_le.sizePolicy().hasHeightForWidth())
+ self.framenumber_average_le.setSizePolicy(sizePolicy)
+ self.framenumber_average_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.framenumber_average_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.framenumber_average_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.framenumber_average_le.setObjectName("framenumber_average_le")
+ self.gridLayout_11.addWidget(self.framenumber_average_le, 0, 2, 1, 1)
+ self.gridLayout_9.addWidget(self.frame_10, 0, 0, 1, 1)
+ self.gridLayout_10.addWidget(self.frame_9, 0, 0, 1, 1)
+ self.frame_8 = QtWidgets.QFrame(self.frame_3)
+ self.frame_8.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.frame_8.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_8.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_8.setObjectName("frame_8")
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_8)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setSpacing(0)
+ self.gridLayout_3.setObjectName("gridLayout_3")
+ spacerItem = QtWidgets.QSpacerItem(399, 15, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.gridLayout_3.addItem(spacerItem, 0, 0, 1, 1)
+ self.t_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.t_label.sizePolicy().hasHeightForWidth())
+ self.t_label.setSizePolicy(sizePolicy)
+ self.t_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.t_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.t_label.setObjectName("t_label")
+ self.gridLayout_3.addWidget(self.t_label, 0, 1, 1, 1)
+ self.hum_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.hum_label.sizePolicy().hasHeightForWidth())
+ self.hum_label.setSizePolicy(sizePolicy)
+ self.hum_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.hum_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.gridLayout_3.addWidget(self.hum_label, 0, 2, 1, 1)
+ self.camera_status_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.camera_status_label.sizePolicy().hasHeightForWidth())
+ self.camera_status_label.setSizePolicy(sizePolicy)
+ self.camera_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.camera_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camera_status_label.setObjectName("camera_status_label")
+ self.gridLayout_3.addWidget(self.camera_status_label, 0, 3, 1, 1)
+ self.gridLayout_10.addWidget(self.frame_8, 1, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_3, 2, 0, 1, 1)
+
+ self.retranslateUi(spectral_Window_phone)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window_phone)
+
+ def retranslateUi(self, spectral_Window_phone):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window_phone.setWindowTitle(_translate("spectral_Window_phone", "光谱窗口"))
+ self.spectral_mode_autoexposure_bt.setText(_translate("spectral_Window_phone", "曝 光"))
+ self.dc_timer_label.setText(_translate("spectral_Window_phone", "计时"))
+ self.spectral_mode_dc_bt.setText(_translate("spectral_Window_phone", "暗 电 流"))
+ self.spectral_mode_wb_bt.setText(_translate("spectral_Window_phone", "白 板"))
+ self.wb_timer_label.setText(_translate("spectral_Window_phone", "计时"))
+ self.spectral_mode_record_bt.setText(_translate("spectral_Window_phone", "采 集"))
+ self.data_type_comboBox.setCurrentText(_translate("spectral_Window_phone", "Ref"))
+ self.data_type_comboBox.setItemText(0, _translate("spectral_Window_phone", "Ref"))
+ self.data_type_comboBox.setItemText(1, _translate("spectral_Window_phone", "DN"))
+ self.data_type_comboBox.setItemText(2, _translate("spectral_Window_phone", "Rad"))
+ self.label_2.setText(_translate("spectral_Window_phone", "文 件"))
+ self.file_number_label.setText(_translate("spectral_Window_phone", "文件号"))
+ self.label_3.setText(_translate("spectral_Window_phone", "自动平均"))
+ self.label_4.setText(_translate("spectral_Window_phone", "连续测量"))
+ self.t_label.setText(_translate("spectral_Window_phone", "温度:无数据"))
+ self.hum_label.setText(_translate("spectral_Window_phone", "湿度:无数据"))
+ self.camera_status_label.setText(_translate("spectral_Window_phone", "光谱仪:连接失败"))
diff --git a/record_system_v26/ui/spectral_Window_phone.ui b/record_system_v26/ui/spectral_Window_phone.ui
new file mode 100644
index 0000000..7962cf0
--- /dev/null
+++ b/record_system_v26/ui/spectral_Window_phone.ui
@@ -0,0 +1,1057 @@
+
+
+ spectral_Window_phone
+
+
+
+ 0
+ 0
+ 540
+ 1175
+
+
+
+ 光谱窗口
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 600
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:40pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 计时
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 白 板
+
+
+ false
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 计时
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QComboBox
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
+ Ref
+
+
+ false
+
+
-
+
+ Ref
+
+
+ -
+
+ DN
+
+
+ -
+
+ Rad
+
+
+
+
+ -
+
+
+ 0
+
+
+ false
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 200
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Microsoft Yahei
+ 61
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:61pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文 件
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 200
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 140
+ 0
+
+
+
+
+ 110
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 自动平均
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 140
+ 0
+
+
+
+
+ 110
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 连续测量
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 399
+ 15
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v27/2record_system_v27.py b/record_system_v27/2record_system_v27.py
new file mode 100644
index 0000000..1e115e6
--- /dev/null
+++ b/record_system_v27/2record_system_v27.py
@@ -0,0 +1,2304 @@
+# -*- coding:utf-8 -*-
+
+'''
+在2record system_v2.2的基础上更新:
+1、影像模式中不采集白板,直接将白板和目标物采集到一起,输出rad影像,转反射率通过envi进行
+2、
+3、
+4、
+5、
+6、
+7、
+'''
+
+# 内置包
+import os, sys, functools, re, shutil, traceback, time
+import subprocess
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+import logging
+
+# 三方包
+import numpy as np
+from ximea import xiapi
+import serial
+import serial.tools.list_ports
+from serial.serialutil import SerialBase, SerialException
+
+# 界面包
+from PyQt5.QtCore import Qt, QObject, QThreadPool, QTimer, QRegExp, pyqtSignal
+# from PyQt5.QtCore import QRectF, pyqtSignal, QRunnable, pyqtSlot, QT_VERSION_STR
+from PyQt5.QtGui import QIntValidator, QRegExpValidator, QPixmap, QImage, QPainterPath
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
+
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from library.matplotlib_display_image_spectral import MatplotlibSpectralViewer, MatplotlibImageViewer
+
+
+# 自己写的包
+from QtImageViewer import QtImageViewer
+from QtSpectralViewer import QtSpectralViewer
+from library.multithread import Worker
+from library.image_reader_writer import ImageReaderWriter
+from library.functions import get_path, get_resource_path, return_file_path
+from library.message_box import MessageBox
+from library.config import ConfigFile
+from library.log import Log
+
+# Qtdesigner所画界面
+from record_system_v27.ui.enter_window import *
+from record_system_v27.ui.image_Window_phone import *
+from record_system_v27.ui.spectral_Window_phone import *
+
+
+# 主窗口
+class EnterWindow(QMainWindow, Ui_enter_Window):
+ def __init__(self, camera, parent=None):
+ super(EnterWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+
+ self.image_mode_phone_bt.clicked.connect(self.image_window)
+
+ self.spectral_mode_bt.clicked.connect(self.spectral_window)
+
+ # self.setEnabled(False) # 先设置本窗口不可用,当打开相机成功后,才设置为可用
+
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ def image_window(self):
+ self.image_window_phone_instance = ImageWindowPhone()
+ self.image_window_phone_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.image_window_phone_instance.show()
+
+ def spectral_window(self):
+ self.spectral_window_instance = SpectralWindow()
+ print(id(self.spectral_window_instance))
+ self.spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.spectral_window_instance.show()
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ self.camstatus_label.setText('相机打开成功!')
+
+ # 如果相机打开成功,界面中label颜色设置为绿色
+ self.change_lable_background_color('green')
+
+ self.setEnabled(True) # 如果相机打开成功,则窗口可用
+ elif imager_status == 1001:
+ self.camstatus_label.setText('相机打开时出现不是ximea错误的未知错误!')
+
+ # 如果相机打开成功,界面中label颜色设置为绿色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 1:
+ self.camstatus_label.setText('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ self.camstatus_label.setText('没有检测到光谱仪!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 57:
+ self.camstatus_label.setText('相机被占用,请关机重启!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 103:
+ pass
+
+ def change_lable_background_color(self, color):
+ pattern = re.compile('background-color:rgb[(](.*)[)]')
+ old_style_sheet = self.camstatus_label.styleSheet()
+
+ if color == 'red': # 如果相机打开失败,界面中label颜色设置为红色
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0)', old_style_sheet)
+ self.camstatus_label.setStyleSheet(new_style_sheet)
+ elif color == 'green': # 如果相机打开成功,界面中label颜色设置为绿色
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0)', old_style_sheet)
+ self.camstatus_label.setStyleSheet(new_style_sheet)
+
+
+class SerialPort(QObject):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ serial_signal = pyqtSignal(object) # 建立信号,用于发射获取的温湿度
+
+ def __init__(self):
+ super(SerialPort, self).__init__()
+
+ # 建立进程池:https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 获取log温度日志的文件夹
+ self.config_file_object = ConfigFile()
+
+ # log
+ self.logger = logging.getLogger('root.serial')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//temperature.log'):
+ with open(self.config_file_object.log_dir + '//temperature.log', 'w') as f:
+ pass
+
+ formatter1 = logging.Formatter('%(asctime)s %(message)s')
+ temperature_file_handler = logging.FileHandler(self.config_file_object.log_dir + '//temperature.log') # 输出到文件
+ temperature_file_handler.setLevel(logging.DEBUG)
+ temperature_file_handler.setFormatter(formatter1)
+
+ self.logger.addHandler(temperature_file_handler)
+
+ self.connect_number = 0 # 记录打开串口的次数
+ self.serial_port = self.open_serial_port()
+
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.receiver_data_from_port)
+ # self.timer.start(1000)
+
+ self.receiver_data_from_port_wraper()
+
+ def open_serial_port(self):
+ self.connect_number += 1
+ port_list = list(serial.tools.list_ports.comports()) # 列出所有可用串口
+ # print(port_list)
+
+ if len(port_list) > 0: # 如果可用串口 >0 个
+ # 打印出所有串口的信息
+ for i in range(0, len(port_list)):
+ print(port_list[i])
+
+ # 打开第一个串口
+ ser = serial.Serial(port_list[0].device)
+ # print('温湿度传感器打开成功!')
+ return ser
+ elif len(port_list) == 0: # 如果可用串口为0个
+ if self.connect_number == 1:
+ self.logger.info('无可用串口,温湿度传感器不可用!')
+ else:
+ self.logger.error('串口连接上之后,断开连接!')
+ return 1 # 如果返回1,则代表没有可用串口;通过1来判断不执行定时器触发:self.timer.start(1000)
+ else: # 其他没有考虑到的情况
+ return 1
+
+ def receiver_data_from_port_wraper(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.receiver_data_from_port)
+
+ self.threadpool.start(worker)
+
+ def receiver_data_from_port(self):
+ '''
+ 定时器QTimer没隔1s调用此函数一次 → 让串口buffer有足够的数据等待读取
+ :return: 无返回值
+
+ 本函数功能:1、串口中接收字节数据,有两种帧 → 代表两种数据
+ 2、判断帧头位置和本帧数据类型
+ 3、判断帧尾 → 等效判断本帧数据是否完全
+ 4、如果数据帧完整 → 解析数据,将温度湿度显示到界面上和写入到文件中
+ '''
+ while True:
+ try:
+ if self.serial_port.in_waiting: # 如果串口buffer有数据等待读取
+ bytes_receive = self.serial_port.read(self.serial_port.inWaiting()) # 读取串口buffer的数据
+ # print(len(bytes_receive))
+
+ # 判断帧头位置,通过正则表达式
+ hex_receive = bytes_receive.hex() # 一个字节需要一个两位16进制数表示,所以:len(hex_receive) = len(bytes_receive) * 2
+ p = re.compile('5a5a*')
+ index_head = [i.start() / 2 for i in re.finditer(p, hex_receive)] # re.finditer()
+ # print(hex_receive)
+ # print(index_head)
+ except SerialException: # 程序打开时,温湿度传感器的串口工作正常;如果程序运行中拔掉串口就会出现此异常
+ self.logger.error('在程序运行中温湿度传感器的串口出现问题!')
+
+ # 再次尝试打开串口
+ self.serial_port = self.open_serial_port()
+ if not isinstance(self.serial_port, int):
+ self.logger.info('再次尝试连接温湿度传感器成功!')
+ else:
+ self.logger.info('再次尝试连接温湿度传感器失败!')
+ except AttributeError: # int object has no attribute: in_waiting
+ self.timer.stop()
+ # self.logger.info('停止定时触发器!')
+ except Exception as e: # 未出现过的异常。当第一次出现时,需要编写代码处理,先写入日志文件(log)
+ self.logger.critical('未知错误!')
+ else: # 当没有捕获到异常时,代表串口数据获取成功 → 执行数据解析
+ # 解析数据
+ try:
+ if len(index_head) != 0:
+ Lux = 1.0
+ T = 1.0
+ P = 1.0
+ Hum = 1.0
+ H = 1.0
+ Lux_full = 0 # 判断光照帧的数据是否完整。0:不完整;1:完整;
+ T_full = 0 # 判断温度帧的数据是否完整。0:不完整;1:完整;
+ try:
+ for i in index_head: # 循环遍历每个帧头
+ if bytes_receive[int(i) + 2] == 21: # 0x15=21,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 8]) & 0xff == bytes_receive[int(i) + 8]: # 判断帧尾是否正确
+ # print('光照帧的帧尾正确!')
+
+ Lux_full = 1 # 如果帧尾,此帧数据数完整的
+ Lux = ((bytes_receive[int(i) + 4] << 24) | (bytes_receive[int(i) + 5] << 16) | (
+ bytes_receive[int(i) + 6] << 8) | bytes_receive[int(i) + 7]) / 100
+ if bytes_receive[int(i) + 2] == 69: # 0x45=69,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 14]) & 0xff == bytes_receive[int(i) + 14]: # 判断帧尾是否正确
+ # print('温度帧的帧尾正确!')
+
+ T_full = 1 # 当执行这段代码时,代表帧头帧尾都正常,此帧数据数完整的
+ T = ((bytes_receive[int(i) + 4] << 8) | bytes_receive[int(i) + 5]) / 100
+ P = ((bytes_receive[int(i) + 6] << 24) | (bytes_receive[int(i) + 7] << 16) | (
+ bytes_receive[int(i) + 8] << 8) | bytes_receive[
+ int(i) + 9]) / 100
+ Hum = ((bytes_receive[int(i) + 10] << 8) | bytes_receive[int(i) + 11]) / 100
+ H = ((bytes_receive[int(i) + 12] << 8) | bytes_receive[int(i) + 13]) / 100
+ except IndexError as e: # 当出现帧头,但是帧头到帧尾的数据不全 → 在判断帧尾是否正确时就会出现索引越界
+ # print('----------------------索引越界!')
+ pass
+ except Exception: # 当出现前面没有解决的异常时,前面的异常捕捉就失效。最后通过异常基类来捕捉 → 代表需要修改代码进行处理的新异常
+ # print('---------------------------------没遇见过的异常')
+ pass
+
+ # 将数据显示和写入文件
+ if Lux_full + T_full == 2: # x + y == 2代表温度帧和光照帧都完整
+ # self.t_label.setVisible(True)
+ # self.hum_label.setVisible(True)
+ # self.t_label.setText('温度:' + str(T))
+ # self.hum_label.setText('湿度:' + str(Hum))
+
+ # print('发送数据')
+
+ self.serial_signal.emit((str(T), str(Hum)))
+ self.logger.debug('%s %s %s', str(T), str(Hum), str(camera.get_temp())) # 将温湿度记录进log文件中
+
+ # print('光照强度:%f' % Lux)
+ # print('温度:%f' % T)
+ # print('气压:%f' % P)
+ # print('湿度:%f' % Hum)
+ # print('海拔:%f' % H)
+ # print()
+ elif Lux_full + T_full == 1:
+ # print('只有一个数据帧是完整的。(光照帧或者温度帧)')
+ # print()
+ pass
+ except UnboundLocalError:
+ # print(2222222222222222222222222222222)
+ # traceback.print_exc()
+ pass
+ except Exception:
+ self.logger.critical('未知错误!')
+ finally: # 不管有没有捕获到异常都会执行,一般用作资源回收
+ pass
+
+ time.sleep(3)
+
+
+# 图像窗口
+class ImageWindowPhone(QDialog, Ui_image_Window_phone):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ arcus_status_signal = pyqtSignal(int) # arcus信号:0→马达未连接;1→马达连接成功;
+ plot_signal = pyqtSignal() # 采集影像时,边采集边刷新显示
+
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(ImageWindowPhone, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:此行代码必须放在show()函数之前
+
+ # 配置文件读取和写入类,配置文件读写和界面分离
+ # 1、采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取
+ # 2、并保存在此类中
+ self.config_file_object = ConfigFile()
+
+ # 数据采集保存类,采集数据并将数据保存在此类中,数据采集和界面分离
+ self.image_camera_operation = CameraOperation(self.config_file_object)
+
+ # 当配置文件读取完成后,就第一时间根据读取的配置文件设置相机曝光、帧率和gain
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+ self.initiate_arcus_speed() # 初始化arcus速度
+
+ # log
+ self.logger = logging.getLogger('root.image_phone')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//image_operate.log'):
+ with open(self.config_file_object.log_dir + '//image_operate.log', 'w') as f:
+ pass
+
+ image_operate_file_handler = logging.FileHandler(self.config_file_object.log_dir + "//image_operate.log") # 输出到文件
+ image_operate_file_handler.setLevel(logging.INFO)
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ image_operate_file_handler.setFormatter(formatter)
+
+ stream_handler = logging.StreamHandler() # 输出到控制台
+ stream_handler.setLevel(logging.DEBUG)
+ stream_handler.setFormatter(formatter)
+ self.logger.addHandler(image_operate_file_handler)
+ self.logger.addHandler(stream_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.serial_signal.connect(self.update_temperature)
+
+ # 采集影像时,边采集边刷新显示
+ self.plot_signal.connect(self.plotimg)
+
+ # 建立进程池:https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化窗口中的值
+ self.framenumber_le.setText(str(self.config_file_object.frame_number))
+ self.framerate_le.setText(str(self.config_file_object.framerate))
+ self.exposure_time_le.setText(str(self.config_file_object.exposure_time))
+ self.arcus_speed_le.setText(str(self.config_file_object.arcus_speed))
+ self.filename_le.setText(self.config_file_object.default_image_name)
+
+ # 显示影像和调焦
+ # self.myImageFigure = MatplotlibImageViewer()
+ self.myImageFigure = QtImageViewer()
+ self.myImageFigure.leftMouseButtonPressed.connect(self.handle_left_click)
+ self.image_glo.addWidget(self.myImageFigure)
+
+ # self.myFocusFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)')
+ self.myFocusFigure = QtSpectralViewer()
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ # 操作光谱仪
+ self.state = 0 # 光谱仪操作状态:曝光=1;暗电流=3;→ 所以只有state==4时才能开始采集影像
+ self.focus_count = 1 # 用于调焦按钮点击计数,取2的余数;当余数为1是执行调焦,当余数为0时停止调焦
+ self.record_count = 1 # 用于采集按钮点击计数,取2的余数;当余数为1是执行采集,当余数为0时停止采集;这是为了使用通过一个按钮控制开始采集和停止采集
+
+ self.image_mode_exposureTime_bt.clicked.connect(self.run)
+ self.image_mode_focus_bt.clicked.connect(self.run) # 停止调焦操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_mode_dc_bt.clicked.connect(self.run)
+ self.image_mode_record_bt.clicked.connect(self.run) # 停止采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.save_bt.clicked.connect(self.run)
+
+ # 手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.exposure_time_le.setValidator(QIntValidator()) # QIntValidator是一个类
+ self.framerate_le.setValidator(QIntValidator())
+ self.framenumber_le.setValidator(QIntValidator())
+
+ my_regex = QRegExp("[a-zA-Z0-9]*")
+ my_validator = QRegExpValidator(my_regex, self.filename_le)
+ self.filename_le.setValidator(my_validator)
+
+ self.exposure_time_le.editingFinished.connect(self.text_edited)
+ # self.exposure_time_le.setPlaceholderText('曝光时间')
+ self.framerate_le.editingFinished.connect(self.text_edited)
+ self.framenumber_le.editingFinished.connect(self.text_edited)
+ self.filename_le.editingFinished.connect(self.text_edited)
+
+ # 马达相关操作
+ self.arcus_left_bt.pressed.connect(self.leftMove)
+ self.arcus_left_bt.released.connect(self.stop)
+ self.arcus_right_bt.pressed.connect(self.rightMove)
+ self.arcus_right_bt.released.connect(self.stop)
+
+ # self.arcus_speed_le.setText(self.arc.write('HSPD'))
+ self.arcus_speed_le.editingFinished.connect(self.text_edited)
+ self.arcus_speed_le.setValidator(QIntValidator())
+
+ self.time = time.time() # 控制arcus两次命令发送的时间间隔
+ self.time_interval = 1
+
+ self.plot_frame_count_multiple = 1 # 用于边采集边在页面中刷新,用于确定该显示多少帧了;如何确定该显示多少帧:self.plot_frame_count_multiple * 帧率
+
+ system_setting.camera_status_signal.connect(self.response_to_imager_status)
+
+ # 检测arcus马达的连接情况
+ self.timer = QTimer(self) # 使用这个定时器,会造成界面卡顿
+ self.timer.timeout.connect(self.test_arcus_status)
+ # self.timer.start(5000)
+
+ self.test_arcus_status_wraper()
+ self.arcus_status_signal.connect(self.response_to_arcus_status)
+
+ # 1)决定采集DN/red;2)反转马达
+ self.rad_dn_comboBox.currentIndexChanged.connect(self.change_rad_dn)
+ self.arcus_direction_bt.clicked.connect(self.change_arcus_direction)
+
+ def change_rad_dn(self):
+ if self.rad_dn_comboBox.currentText() == 'rad':
+ self.image_camera_operation.record_rad_bool = True
+ elif self.rad_dn_comboBox.currentText() == 'dn':
+ self.image_camera_operation.record_rad_bool = False
+
+ def change_arcus_direction(self):
+ if self.image_camera_operation.arcus_reverse_while_record == False:
+ self.image_camera_operation.arcus_reverse_while_record = True
+ self.change_widget_background_color(self.arcus_direction_bt, 'red')
+ elif self.image_camera_operation.arcus_reverse_while_record == True:
+ self.image_camera_operation.arcus_reverse_while_record = False
+ self.change_widget_background_color(self.arcus_direction_bt, 'gray')
+
+ def test_arcus_status_wraper(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.test_arcus_status)
+
+ self.threadpool.start(worker)
+
+ def test_arcus_status(self):
+ while True:
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' DN'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+ if 'Arcus device connected' in output.decode('utf-8'):
+ self.arcus_status_signal.emit(1)
+ elif 'No arcus devices' in output.decode('utf-8'):
+ self.arcus_status_signal.emit(0)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+ if 'Arcus device connected' in output2.decode('utf-8'):
+ self.arcus_status_signal.emit(1)
+ elif 'No arcus devices' in output2.decode('utf-8'):
+ self.arcus_status_signal.emit(0)
+
+ time.sleep(4) # 本线程沉睡3秒
+
+ def response_to_arcus_status(self, arcus_status):
+ if arcus_status == 0:
+ self.arcus_status_label.setText('马达:连接失败!')
+ self.change_widget_background_color(self.arcus_status_label, 'red')
+ elif arcus_status == 1:
+ self.arcus_status_label.setText('马达:连接正常!')
+ self.change_widget_background_color(self.arcus_status_label, 'green')
+
+ def response_to_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ # print('相机打开成功!')
+
+ try:
+ temperature = camera.get_temp()
+ except Exception:
+ temperature = None
+
+ self.camera_status_label.setText('光谱仪:' + str(temperature))
+
+ self.change_widget_background_color(self.camera_status_label, 'green')
+ elif imager_status == 1001:
+ print('相机打开时出现不是ximea错误的未知错误!')
+ elif imager_status == 1:
+ # print('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ self.camera_status_label.setText('光谱仪:断开连接')
+ self.change_widget_background_color(self.camera_status_label, 'red')
+
+ self.setEnabled(False)
+ self.close()
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ print('没有检测到光谱仪!')
+ elif imager_status == 103:
+ pass
+
+ def leftMove(self):
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J-'
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' CLR EO=1 J-'
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+
+ # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ print('左移出错output', output)
+ print('左移出错error', error)
+
+ def rightMove(self):
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J+'
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' CLR EO=1 J+'
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+
+ # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ print('右移出错output', output)
+ print('右移出错error', error)
+
+ def stop(self):
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py STOP'
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' STOP'
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+
+ # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ print('停止出错output', output)
+ print('停止出错error', error)
+
+ def handle_left_click(self, x, y):
+ # 画出光谱
+ try:
+ row = int(y)
+ column = int(x)
+ # print("Pixel (row=" + str(row) + ", column=" + str(column) + ")")
+
+ _, _, img = ImageReaderWriter.read_img('corning410_test', column, row, 1, 1)
+
+ if isinstance(img, np.ndarray): # 如果点击到图像之外,img就是NoneType,就不重画光谱
+ # print('点击有效')
+
+ self.myFocusFigure.plot_wrap(self.image_camera_operation.wave(model='array'), img[:, 0, 0])
+ except TypeError:
+ pass
+ # print('有错')
+ # self.logger.critical('TypeError:', exc_info=True)
+ except Exception:
+ self.logger.critical('点击显示光谱时出现未知错误:', exc_info=True)
+ traceback.print_exc()
+
+ # 手动修改界面中的值后,为相机重新设置如下参数:exposure, gain, framerate
+ def text_edited(self):
+ try:
+ # 将改变值1)保存到配置文件对象,供程序运行使用2)写入到配置文件,供程序下次打开读取
+ self.config_file_object.image_signal.emit(
+ {'exposure_time': int(self.exposure_time_le.text()),
+ 'framerate': int(self.framerate_le.text()), 'frame_number': int(self.framenumber_le.text()),
+ 'default_image_name': self.filename_le.text(), 'arcus_speed': self.arcus_speed_le.text()})
+ except ValueError:
+ self.x = MessageBox('请输入正确的值!')
+ self.x.exec()
+ except Exception:
+ self.logger.critical('设置曝光/gain/帧率/帧数时出现未知错误!', exe_info=True)
+
+ if self.sender().objectName() == 'exposure_time_le':
+ self.state = 1 # 手动改变曝光时间后,强制让用户重新采集暗电流+白板
+
+ print('exposure_time_le改变')
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if self.sender().objectName() == 'framerate_le':
+ self.state = 0 # 改变帧率后,需要重新曝光
+
+ print('framerate_le改变')
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if self.sender().objectName() == 'framenumber_le':
+ self.image_camera_operation.create_rgb()
+
+ if self.sender().objectName() == 'arcus_speed_le':
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' HSPD=' + str(self.arcus_speed_le.text())
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=1)
+
+ # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ print('改变arcus速度出错output', output)
+ print('改变arcus速度出错error', error)
+
+ def initiate_arcus_speed(self):
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' HSPD=' + str(self.config_file_object.arcus_speed)
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ # print(output)
+ # print(error)
+ print('初始化速度ok!')
+
+ def update_temperature(self, data):
+ try:
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+
+ self.change_widget_background_color(self.t_label, 'green')
+ self.change_widget_background_color(self.hum_label, 'green')
+ except:
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def timer_start(self):
+ '''
+ 本函数目的是在self.timer.start(1000)外包裹一层(有点装饰器的感觉),加入判断:
+ 1、如果self.serial_port为串口类型,就触发定时器self.timer.start(1000)
+ 2、如果self.serial_port == 1(为int类型),则代表硬件中没有温湿度传感器,就没必要触发定时器self.timer.start(1000)
+ :return: 无返回值
+ '''
+
+ if isinstance(self.serial_port, serial.serialwin32.Serial):
+ self.timer.start(1000)
+ elif isinstance(self.serial_port, int):
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ else:
+ pass
+
+ def plotimg(self):
+ try:
+ if self.qt_sender == 'image_mode_record_bt':
+ frame_number_to_plot = self.plot_frame_count_multiple * self.config_file_object.framerate
+
+ self.framenumber_recorded_label.setText(str(frame_number_to_plot))
+
+ img = np.dstack((self.image_camera_operation.rgb[2, 0:frame_number_to_plot, :], self.image_camera_operation.rgb[1, 0:frame_number_to_plot, :],
+ self.image_camera_operation.rgb[0, 0:frame_number_to_plot, :]))
+
+ self.myImageFigure.setImage(img)
+
+ self.plot_frame_count_multiple += 1
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.myImageFigure.setImage(self.image_camera_operation.image_container)
+
+ n = int(self.image_camera_operation.image_container.shape[0] / 2)
+ self.myFocusFigure.plot_wrap(self.image_camera_operation.image_container[n, :])
+
+ # worker = Worker(self.myImageFigure.setImage, self.image_camera_operation.image_container)
+ # self.threadpool.start(worker)
+ except:
+ self.logger.critical('未知错误--界面中绘制影像和光谱时!\n%s', exc_info=True)
+
+ # 调焦、采集暗电流、采集白板、采集影像 都通过此函数
+ def run(self):
+ try:
+ self.qt_sender = self.sender().objectName()
+
+ if self.qt_sender == 'image_mode_focus_bt':
+ if self.focus_count % 2 == 1:
+ self.image_mode_focus_bt.setText('停止调焦')
+ self.core_operation()
+ self.focus_count += 1
+
+ self.change_widget_background_color(self.image_mode_focus_bt, 'red')
+ elif self.focus_count % 2 == 0: # 停止调焦操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_camera_operation.focus = False
+ self.image_mode_focus_bt.setText('调焦')
+ self.focus_count += 1
+ elif self.qt_sender == 'image_mode_exposureTime_bt':
+ self.state = 1
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_exposureTime_bt, 'red')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ self.x.exec()
+ elif self.state == 1 or self.state == 4: # 正常采集暗电流
+ self.x = MessageBox('请先确认镜头盖已安装!')
+ self.x.exec()
+
+ self.state = 4
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_dc_bt, 'red')
+ elif self.qt_sender == 'image_mode_record_bt':
+ if self.record_count % 2 == 1:
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ self.x.exec()
+ elif self.state == 1: #
+ self.x = MessageBox('请采集暗电流!')
+ self.x.exec()
+ elif self.state == 4: # 正常采集影像,采集DN/反射率的判断 放在CameraOperation类中
+ self.record_count += 1
+ self.plot_frame_count_multiple = 1 # 每次点击采集按钮都将此变量设置为1,用于正常边采集影像边在界面中显示影像
+
+ self.image_mode_record_bt.setText('停止采集')
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_record_bt, 'red')
+ elif self.record_count % 2 == 0: # 停止采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_camera_operation.record = False
+ self.image_mode_record_bt.setText('采集')
+ elif self.qt_sender == 'save_bt':
+ worker = Worker(self.savedata)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+
+ self.threadpool.start(worker)
+
+ self.change_widget_background_color(self.save_bt, 'red')
+ except Exception:
+ traceback.print_exc()
+
+ # 改变按钮三态中普通态的背景颜色
+ def change_widget_background_color(self, qt_widget, color):
+ pattern = re.compile('background-color(.*)(normal\*/)')
+ old_style_sheet = qt_widget.styleSheet()
+
+ if color == 'red':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'green':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'gray':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(225 , 225 , 225);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+
+ def core_operation(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.image_camera_operation.start_AcquireData, camera, self.qt_sender, self.plot_signal)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ self.disable_bt(True)
+
+ def disable_bt(self, bool):
+ # 两个if判断存在的原因:调焦/停止调焦(采集/停止采集)使用同一个按钮,所以不能将其设置为不可用
+ if self.qt_sender !='image_mode_focus_bt':
+ self.image_mode_focus_bt.setDisabled(bool)
+ if self.qt_sender != 'image_mode_record_bt':
+ self.image_mode_record_bt.setDisabled(bool)
+
+ if bool == False: # 操作完成后设置为可用
+ self.image_mode_record_bt.setDisabled(bool)
+ self.image_mode_focus_bt.setDisabled(bool)
+
+ self.image_mode_exposureTime_bt.setDisabled(bool)
+ self.image_mode_dc_bt.setDisabled(bool)
+ self.save_bt.setDisabled(bool)
+ self.arcus_left_bt.setDisabled(bool)
+ self.arcus_right_bt.setDisabled(bool)
+
+ self.exposure_time_le.setDisabled(bool)
+ self.framerate_le.setDisabled(bool)
+ self.arcus_speed_le.setDisabled(bool)
+ self.framenumber_le.setDisabled(bool)
+ self.filename_le.setDisabled(bool)
+
+ self.rad_dn_comboBox.setDisabled(bool)
+ self.arcus_direction_bt.setDisabled(bool)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if traceback_info[1].status == 1: # 在ximea的API中代表"Invalid handle":相机断开连接
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.error('自动曝光失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.error('调焦失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.error('采集暗电流失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.error('采集影像失败:相机断开连接!\n%s', traceback_info[2])
+ elif traceback_info[1].status == 56: # 在ximea的API中代表"No Devices Found":在执行cam.open_device()时,无相机打开
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.error('自动曝光失败:无相机可供打开!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.error('调焦失败:无相机可供打开!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.error('采集暗电流失败:无相机可供打开\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.error('采集影像失败:无相机可供打开\n%s', traceback_info[2])
+ elif traceback_info[1].status == 12: # 在ximea的API中代表"Not supported":当相机正在采集数据时,执行代码cam.set_imgdataformat('XI_RAW16')
+ pass
+ elif traceback_info[1].status == 41: # 在ximea的API中代表"Acquisition already started":相机已经开始采集数据
+ pass
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'save_bt':
+ self.logger.error('保存影像失败--影像名不正确!\n%s', traceback_info[2])
+
+ self.x = MessageBox('请输入正确的影像名!')
+ self.x.exec()
+ elif traceback_info[0] == FileNotFoundError:
+ if self.qt_sender == 'save_bt':
+ self.logger.error('保存影像失败--没有采集影像!\n%s', traceback_info[2])
+
+ self.x = MessageBox('请先采集影像!')
+ self.x.exec()
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ print('operate_failed函数运行成功!')
+
+ def operate_success(self):
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.info('自动曝光成功----------------!')
+
+ self.image_mode_exposureTime_bt.setText(re.sub('✔', '', self.image_mode_exposureTime_bt.text()) + '✔')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.info('调焦成功!')
+
+ self.image_mode_focus_bt.setText(re.sub('✔', '', self.image_mode_focus_bt.text()) + '✔')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.info('采集暗电流成功!')
+
+ self.image_mode_dc_bt.setText(re.sub('✔', '', self.image_mode_dc_bt.text()) + '✔')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.info('采集影像成功!')
+
+ self.image_mode_record_bt.setText('采集')
+ self.image_mode_record_bt.setDisabled(True) # 要等马达回到初始位置才能用
+ self.record_count += 1
+
+ self.image_mode_record_bt.setText(re.sub('✔', '', self.image_mode_record_bt.text()) + '✔')
+
+ self.save_bt.setText(re.sub('✔', '', self.save_bt.text()))
+ elif self.qt_sender == 'save_bt':
+ self.save_bt.setText(re.sub('✔', '', self.save_bt.text()) + '✔')
+
+ self.image_mode_record_bt.setText(re.sub('✔', '', self.image_mode_record_bt.text()))
+
+ self.logger.info('保存影像成功!')
+
+ worker = Worker(self.wwww)
+ self.threadpool.start(worker)
+
+ def wwww(self):
+ while True:
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' PX'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+ if 'arcus is return to initial position' in output.decode('utf-8'):
+ self.ssss()
+
+ break
+ elif 'No arcus devices' in output.decode('utf-8'):
+ self.ssss()
+
+ break
+ elif 'arcus is still returning' in output.decode('utf-8'):
+ pass
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+ if 'Arcus device connected' in output2.decode('utf-8'):
+ self.ssss()
+
+ break
+ elif 'No arcus devices' in output2.decode('utf-8'):
+ self.ssss()
+
+ break
+
+ def ssss(self):
+ self.disable_bt(False)
+
+ # 当操作成功后,所有按钮都变为初始颜色:灰色
+ self.change_widget_background_color(self.image_mode_exposureTime_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_focus_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_dc_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_record_bt, 'gray')
+ self.change_widget_background_color(self.save_bt, 'gray')
+
+ # 保存影像数据
+ def savedata(self):
+ self.disable_bt(True) # 因为保存影像所需时间较多,所以需要将此行代码放在最前面
+
+ # 保存路径
+ # filename = "%s%s%s" % (re.sub('/', '\\\\', self.config_file_object.image_dir), '\\', self.config_file_object.default_image_name)
+ filename, file_number = return_file_path([], self.config_file_object.image_dir,
+ self.config_file_object.default_image_name)
+
+ # 保存影像和头文件
+ imagefile = "%s%s%s" % (os.getcwd(), '\\', 'corning410_test')
+ shutil.copyfile(imagefile, filename)
+ shutil.copyfile("%s%s" % (imagefile, '.hdr'), "%s%s" % (filename, '.hdr'))
+
+ self.file_number_label.setText(str(file_number))
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和self.config对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+ try:
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ self.exposure_time_le.setText(str(result[0]))
+
+ # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为self.config.exposure_time的旧值
+ self.config_file_object.exposure_time = result[0]
+ self.config_file_object.gain = result[1]
+
+ try:
+ # 将自动曝光值保存到配置文件中
+ self.config_file_object.image_signal.emit({'exposure_time': result[0], 'gain': result[1]})
+ except:
+ traceback.print_exc()
+
+
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if result[2] == 1:
+ self.x = MessageBox('光线不足,曝光时间已设置为最大!')
+ self.x.exec()
+ self.image_camera_operation.autoexposure_feedback = 0
+ except:
+ traceback.print_exc()
+
+ def closeEvent(self, a0: QtGui.QCloseEvent):
+ camera.stop_acquisition()
+
+
+# 光谱窗口
+class SpectralWindow(QDialog, Ui_spectral_Window_phone):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ progress_bar_and_plot_spectral_signal = pyqtSignal(int)
+
+ def __init__(self, parent=None):
+ super(SpectralWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:此行代码必须放在show()函数之前
+
+ # 数据采集保存类,采集数据并将数据保存在此类中,数据采集和界面分离
+
+ # 配置文件读取和写入类,配置文件读写和界面分离
+ # 1、采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取
+ # 2、并保存在此类中
+ self.config_file_object = ConfigFile()
+
+ self.spectral_camera_operation = SpectralCameraOperation(self.config_file_object)
+
+ self.progress_bar_and_plot_spectral_signal.connect(self.plot_save_spectral)
+
+ self.state = 0 # 光谱仪操作状态:曝光=1;暗电流=3;白板=5 → 所以只有state==9时才能开始采集光谱
+ self.dc_time = time.time() # 用于暗电流计时(从采集成功后那一刻开始)
+ self.dc_timer = QTimer(self)
+ self.dc_timer.timeout.connect(self.dc_timer_slot)
+
+ self.wb_time = time.time() # 用于暗电流计时(从采集成功后那一刻开始)
+ self.wb_timer = QTimer(self)
+ self.wb_timer.timeout.connect(self.wb_timer_slot)
+
+ self.progressBar.setMaximum(self.config_file_object.spectral_number)
+ self.progressBar.setValue(0)
+
+ # log
+ self.logger = logging.getLogger('root.spectral')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//spectral_operate.log'):
+ with open(self.config_file_object.log_dir + '//spectral_operate.log', 'w') as f:
+ pass
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ spectral_operate_file_handler = logging.FileHandler(self.config_file_object.log_dir + "//spectral_operate.log") # 输出到文件
+ spectral_operate_file_handler.setLevel(logging.INFO)
+ spectral_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(spectral_operate_file_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.serial_signal.connect(self.update_temperature)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化值
+ self.filename_le.setText(self.config_file_object.default_spectral_name)
+ self.spectral_number_le.setText(str(self.config_file_object.spectral_number))
+ self.framenumber_average_le.setText(str(self.config_file_object.framenumber_average))
+ self.autoexposure_le.setText(str(self.config_file_object.exposure_time_spectral))
+
+ # 显示光谱和align
+ # self.spectralFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
+ self.spectralFigure = QtSpectralViewer(ylabel_and_range='reflectance')
+ self.spe_glo.addWidget(self.spectralFigure)
+
+ #操作光谱仪
+ # self.dc_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.wb_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ # self.record_bt.clicked.connect(functools.partial(spectral_camera_operation.start_AcquireData, camera))
+ self.spectral_mode_autoexposure_bt.clicked.connect(self.run)
+ self.spectral_mode_wb_bt.clicked.connect(self.run) # 曝光 + 采集白板
+ self.spectral_mode_dc_bt.clicked.connect(self.run)
+ self.spectral_mode_record_bt.clicked.connect(self.run)
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filename_le.editingFinished.connect(self.onchange)
+ my_regex1 = QRegExp("[a-zA-Z0-9]*")
+ my_validator1 = QRegExpValidator(my_regex1, self.filename_le)
+ self.filename_le.setValidator(my_validator1)
+
+ self.autoexposure_le.editingFinished.connect(self.onchange)
+ my_regex2 = QRegExp("[0-9]*")
+ my_validator2 = QRegExpValidator(my_regex2, self.autoexposure_le)
+ self.autoexposure_le.setValidator(my_validator2)
+
+ self.spectral_number_le.editingFinished.connect(self.onchange)
+ self.framenumber_average_le.editingFinished.connect(self.onchange)
+ my_regex3 = QRegExp("[0-9]*")
+ my_validator3 = QRegExpValidator(my_regex2, self.autoexposure_le)
+ self.spectral_number_le.setValidator(my_validator2)
+ self.framenumber_average_le.setValidator(my_validator2)
+
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ self.hpi_temperature = None
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ # print('相机打开成功!')
+
+ try:
+ temperature = camera.get_temp()
+ except Exception:
+ temperature = None
+
+ self.camera_status_label.setText('光谱仪:' + str(temperature))
+ self.change_widget_background_color(self.camera_status_label, 'green')
+ elif imager_status == 1001:
+ print('相机打开时出现不是ximea错误的未知错误!')
+ elif imager_status == 1:
+ # print('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ self.camera_status_label.setText('光谱仪:断开连接')
+ self.change_widget_background_color(self.camera_status_label, 'red')
+
+ self.setEnabled(False)
+ self.close()
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ print('没有检测到光谱仪!')
+ elif imager_status == 103:
+ pass
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ try:
+ if self.sender().objectName() == 'autoexposure_le':
+ self.state = 1 # 手动改变曝光时间后,需要强制让用户重新采集暗电流和白板
+
+ exposure_time_tmp = int(self.autoexposure_le.text())
+
+ self.config_file_object.spectral_signal.emit({'exposure_time_spectral': exposure_time_tmp})
+
+ camera.set_exposure(exposure_time_tmp) # 曝光时间单位为微秒,1s共有1000000微秒
+ # camera.set_gain(int(float(self.config_file_object.gain))) # int('0.0')会报错,int(float('0.0'))不会报错
+
+ self.logger.info('手动改变曝光时间!')
+ elif self.sender().objectName() == 'framenumber_average_le':
+ framenumber_average_tmp = int(self.framenumber_average_le.text())
+
+ self.config_file_object.spectral_signal.emit({'framenumber_average': framenumber_average_tmp})
+
+ self.spectral_camera_operation.create_image_container(framenumber_average_tmp)
+
+ self.logger.info('手动改变每条光谱的平均帧数!')
+ elif self.sender().objectName() == 'spectral_number_le':
+ spectral_number_tmp = int(self.spectral_number_le.text())
+
+ self.config_file_object.spectral_signal.emit({'spectral_number': spectral_number_tmp})
+
+ self.progressBar.setMaximum(spectral_number_tmp)
+ self.progressBar.setValue(0)
+
+ self.spectral_camera_operation.create_spectral_container(spectral_number_tmp)
+
+ self.logger.info('手动改变保存的光谱数!')
+ elif self.sender().objectName() == 'filename_le':
+ filename = self.filename_le.text()
+
+ if filename != '':
+ self.config_file_object.spectral_signal.emit({'default_spectral_name': filename})
+
+ self.logger.info('改变光谱文件名!')
+ except:
+ traceback.print_exc()
+
+ def plot_save_spectral(self, x):
+ try:
+ self.progressBar.setValue(x)
+
+ # 画出光谱
+ if self.data_type_comboBox.currentText() == 'DN':
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn[:, 0], self.spectral_camera_operation.spectral_dn[:, x])
+ if self.data_type_comboBox.currentText() == 'Rad':
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn[:, 0], self.spectral_camera_operation.spectral_rad[:, x])
+ if self.data_type_comboBox.currentText() == 'Ref':
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn[:, 0], self.spectral_camera_operation.spectral_ref[:, x])
+
+ # 保存光谱
+ filename_dn, file_number_dn = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_dn', model='spectral')
+ filename_rad, file_number_rad = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_rad', model='spectral')
+ filename_ref, file_number_ref = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_ref', model='spectral')
+ # print(filename_ref)
+
+ header_dn = self.get_spectral_metadata('DN')
+ header_rad = self.get_spectral_metadata('RAD')
+ header_ref = self.get_spectral_metadata('REF')
+
+ np.savetxt(filename_dn, self.spectral_camera_operation.spectral_dn[:, [0, x]], fmt='%f', header=header_dn)
+ np.savetxt(filename_rad, self.spectral_camera_operation.spectral_rad[:, [0, x]], fmt='%f', header=header_rad)
+ np.savetxt(filename_ref, self.spectral_camera_operation.spectral_ref[:, [0, x]], fmt='%f', header=header_ref)
+
+ self.file_number_label.setText(str(file_number_dn))
+ except:
+ traceback.print_exc()
+
+ def get_spectral_metadata(self, data_type_str):
+
+ record_time = "%s%s" % ('RecordTime = ', str(datetime.datetime.now()))
+ SN = 'SN = 0001'
+ exposure_time = "%s%s" % ('ExposureTime = ', str(camera.get_exposure()))
+ data_type = "%s%s" % ('DataType = ', data_type_str)
+ sensor_temperature = "%s%s" % ('sensor_temperature = ', str(camera.get_temp()))
+ hpi_temperature = "%s%s" % ('hpi_temperature = ', str(self.hpi_temperature))
+
+ header = '%s%s%s%s%s%s%s%s%s%s%s' % (
+ record_time, '\n', SN, '\n', exposure_time, '\n', data_type, '\n', sensor_temperature, '\n', hpi_temperature)
+ return header
+
+ def update_temperature(self, data):
+ try:
+ self.hpi_temperature = data[0]
+
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+
+ self.change_widget_background_color(self.t_label, 'green')
+ self.change_widget_background_color(self.hum_label, 'green')
+ except:
+ traceback.print_exc()
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def dc_timer_slot(self):
+ now = time.time()
+ x = now - self.dc_time
+ self.dc_timer_label.setText(str(int(x)) + 's')
+
+ def wb_timer_slot(self):
+ now = time.time()
+ x = now - self.wb_time
+ self.wb_timer_label.setText(str(int(x)) + 's')
+
+ def run(self):
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ print('SpectralWindow采集曝光')
+
+ self.logger.info('曝光...')
+
+ self.state = 1
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_autoexposure_bt, 'red')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ try:
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ self.x.exec()
+ elif self.state == 1 or self.state == 4 or self.state == 9:
+ self.x = MessageBox('请先确认光纤盖已安装!')
+ self.x.exec()
+
+ self.logger.info('采集暗电流...')
+ self.state = 4
+
+ # 暗电流计时
+ self.dc_time = time.time()
+ self.dc_timer.start(2000)
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_dc_bt, 'red')
+ except:
+ traceback.print_exc()
+ elif self.qt_sender == 'spectral_mode_wb_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光+暗电流!')
+ self.x.exec()
+ elif self.state == 1:
+ self.x = MessageBox('请先采集暗电流!')
+ self.x.exec()
+ elif self.state == 4 or self.state == 9:
+ self.logger.info('采集白板...')
+ self.state = 9
+
+ # 白板计时
+ self.wb_time = time.time()
+ self.wb_timer.start(2000)
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_wb_bt, 'red')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光+暗电流+白板')
+ self.x.exec()
+ elif self.state == 1:
+ self.x = MessageBox('请先暗电流+白板')
+ self.x.exec()
+ elif self.state == 4:
+ self.x = MessageBox('请先白板')
+ self.x.exec()
+ elif self.state == 9:
+ self.logger.info('采集光谱...')
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.spectral_mode_record_bt, 'red')
+
+ # 改变按钮三态中普通态的背景颜色
+ def change_widget_background_color(self, qt_widget, color):
+ pattern = re.compile('background-color(.*)(normal\*/)')
+ old_style_sheet = qt_widget.styleSheet()
+
+ if color == 'red':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'green':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'gray':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(225 , 225 , 225);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和self.config_file_object对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ self.autoexposure_le.setText(str(result[0]))
+
+ # # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为self.config_file_object.exposure_time的旧值
+ # self.config_file_object.exposure_time = result[0]
+ # self.config_file_object.gain = result[1]
+
+ def core_operation(self):
+ worker = Worker(self.spectral_camera_operation.start_AcquireData, camera, self.qt_sender,
+ self.progress_bar_and_plot_spectral_signal)
+ worker.signals.finished.connect(self.operate_success)
+ worker.signals.error.connect(self.operate_failed)
+
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ self.disable_bt_le(True)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if self.qt_sender == 'spectral_mode_wb_bt':
+ self.logger.error('曝光/白板失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.logger.error('align 失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.logger.error('采集暗电流失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.error('采集光谱失败:光谱仪正在工作中,请稍等!\n%s', traceback_info[2])
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.error('保存光谱失败!\n%s', traceback_info[2])
+
+ self.x = MessageBox('请输入正确的光谱名!')
+ self.x.exec()
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ self.logger.info('曝光成功!')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'spectral_mode_wb_bt':
+ self.logger.info('采集白板成功!')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.logger.info('align successfully!')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.info('采集光谱成功!')
+
+ self.disable_bt_le(False)
+
+ # 当操作成功后,所有按钮都变为初始颜色:灰色
+ self.change_widget_background_color(self.spectral_mode_autoexposure_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_dc_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_wb_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_record_bt, 'gray')
+
+ def disable_bt_le(self, bool):
+ self.spectral_mode_autoexposure_bt.setDisabled(bool)
+ self.spectral_mode_dc_bt.setDisabled(bool)
+ self.spectral_mode_wb_bt.setDisabled(bool)
+ self.spectral_mode_record_bt.setDisabled(bool)
+
+ self.spectral_number_le.setDisabled(bool)
+ self.framenumber_average_le.setDisabled(bool)
+ self.autoexposure_le.setDisabled(bool)
+ self.filename_le.setDisabled(bool)
+
+ def closeEvent(self, a0: QtGui.QCloseEvent):
+ camera.stop_acquisition()
+
+
+# 影像模式类:相关的函数和变量
+class CameraOperation(object):
+ def __init__(self, config_file_object):
+ self.config_file_object = config_file_object
+
+ # 转辐亮度
+ self.rad_or_not = False
+ if self.config_file_object.binning == 1:
+ self.img_gain = get_resource_path('./data/lens_bin1_gain_SN0073')
+ self.cal_it = 7289
+ elif self.config_file_object.binning == 2:
+ self.img_gain = get_resource_path('./data/lens_bin2_gain_SN0073')
+ self.cal_it = 1654
+ _, _, self.gain = ImageReaderWriter.read_img(self.img_gain)
+
+ self.gain = self.gain.astype(np.float32)
+ self.target_it = None
+ self.gain_scale = None
+
+ #
+ self.arcus_reverse_while_record = False
+ self.record_rad_bool = True # True → 采集rad影像,False → 采集dn影像
+
+ # 开始采集数据
+ self.image_dc = None # 此变量用于存储采集到的暗电流影像
+ self.focus = True # 用于停止调焦
+ self.record = True # 用于停止采集
+ self.img_datatype = 2 # 在头文件中确定影像数据类型:Integer(np.int16) → A 16-bit signed integer ranging from -32,768 to +32,767.
+
+ self.autoexposure_feedback = 0 # 指示:自动曝光所得到的shutter值是否为最大;如果为最大→值设置为1
+
+ # 创建rgb数据,用于在界面中显示
+ self.create_rgb()
+
+ def create_rgb(self):
+ self.rgb = np.ones((3, int(self.config_file_object.frame_number), self.config_file_object.end_column - self.config_file_object.start_column))
+
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposure_gain_framerate(self, cam):
+ # settings,cam.set_param("exposure",10000)
+ cam.set_framerate(self.config_file_object.framerate)
+ cam.set_exposure(self.config_file_object.exposure_time) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(self.config_file_object.gain) #int('0.0')会报错,int(float('0.0'))不会报错
+
+ def start_AcquireData(self, cam, qt_sender, plot_signal=None): # qt_sender是指qt窗口中事件的发生者
+ '''
+ :param cam: 实例化的相机句柄
+ :param qt_sender: 调用本方法时,点击的界面上的按钮名;
+ :param plot_signal:
+ :return:
+ '''
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ # 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+ # 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype('= 4090:
+ cam.set_exposure(int(0.9 * cam.get_exposure()))
+
+ cam.start_acquisition()
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ image_raw_numpy = img.get_image_data_numpy()
+
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not self.focus:
+ self.focus = True
+
+ cam.start_acquisition()
+
+ while self.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ self.image_container = image_raw_numpy[
+ self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+
+ if plot_signal is not None:
+ plot_signal.emit()
+
+ # 调焦完成之后,将相机的曝光和帧率设置为配置文件中的值
+ self.set_exposure_gain_framerate(cam)
+
+ if qt_sender == 'image_mode_exposureTime_bt':
+ print('start_AcquireData--自动曝光运行开始')
+
+ # 设置自动曝光的CCD--roi
+ cam.set_framerate(self.config_file_object.framerate)
+ cam.set_aeag_roi_offset_x(self.config_file_object.start_column)
+ cam.set_aeag_roi_offset_y(self.config_file_object.start_row)
+ cam.set_aeag_roi_height(self.config_file_object.end_row - self.config_file_object.start_row)
+ cam.set_aeag_roi_width(self.config_file_object.end_column - self.config_file_object.start_column)
+ # cam.set_exp_priority(1) # Exposure priority (0.8 - exposure 80%, gain 20%).XI_PRM_EXP_PRIORITY
+ # cam.set_ae_max_limit(24000) # Maximum time (us) used for exposure in AEAG procedureXI_PRM_AE_MAX_LIMIT
+ # cam.set_ag_max_limit(12)
+ # cam.set_aeag_level(50) # Average intensity of output signal AEAG should achieve(in %)XI_PRM_AEAG_LEVEL
+ # 还有两个不知怎么用的参数:XI_PRM_GAIN_SELECTOR or "gain_selector"和XI_PRM_SHUTTER_TYPE or "shutter_type"
+
+ # 使用相机自动曝光功能得到初始曝光值
+ cam.enable_aeag() # 开启自动曝光
+ cam.start_acquisition()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ cam.disable_aeag() # 关闭自动曝光
+
+ # 根据自动曝光所得初始曝光值,循环迭代获取不过曝的曝光值
+ image_raw_numpy = img.get_image_data_numpy()
+ while image_raw_numpy.max() >= 2730:
+ cam.set_exposure(int(0.9 * cam.get_exposure()))
+
+ cam.start_acquisition()
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ image_raw_numpy = img.get_image_data_numpy()
+
+ # 如果因为光线不足曝光值达到了最大,就将曝光反馈变量设置为1
+ if cam.get_exposure() > int(1 / self.config_file_object.framerate * 10**6):
+ cam.set_exposure(int(1 / self.config_file_object.framerate * 10**6))
+ self.autoexposure_feedback = 1
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+ # 计算gain
+ self.target_it = cam.get_exposure()
+ self.gain_scale = self.cal_it / self.target_it
+ self.gain = self.gain * self.gain_scale
+
+ print('start_AcquireData--自动曝光运行结束')
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'image_mode_dc_bt':
+ framenumber = 10
+ image_container = np.empty((
+ self.config_file_object.end_row - self.config_file_object.start_row, framenumber,
+ self.config_file_object.end_column - self.config_file_object.start_column))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[
+ self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+
+ image_container = image_container.mean(axis=1)
+
+ self.image_dc = image_container
+
+ # 如果点击“采集”按钮,自动去除暗电流,并且转化成反射率
+ if qt_sender == 'image_mode_record_bt':
+ frameCount = 1 # 统计采集的帧数,用于停止采集使用
+
+ # 当停止采集后,再次开始采集需要将cls.record的值从False变为True
+ if not self.record:
+ self.record = True
+
+ # 启动马达
+ self.arcus_start()
+
+ # 开始采集数据 并且 将数据写入到硬盘中
+ cam.start_acquisition()
+ with open('corning410_test', 'wb') as f:
+
+ print('Starting data acquisition...')
+ startTime = datetime.datetime.now()
+
+ while self.record:
+ cam.get_image(img) # get data and pass them from camera to img
+ # image_raw_numpy.dtype -> dtype('
+
+ enter_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+ -
+
+
+ true
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
+ 正在打开相机...
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 光谱模式
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 影像模式
+
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v27/ui/image_Window_phone - 副本 (2).ui b/record_system_v27/ui/image_Window_phone - 副本 (2).ui
new file mode 100644
index 0000000..ac44ed4
--- /dev/null
+++ b/record_system_v27/ui/image_Window_phone - 副本 (2).ui
@@ -0,0 +1,1358 @@
+
+
+ image_Window_phone
+
+
+ true
+
+
+
+ 0
+ 0
+ 531
+ 1174
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 调 焦
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 保 存
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 140
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 命 名
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 积分时间
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 160
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 马 达
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ <
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ >
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ rad
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 反转
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 233
+ 12
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 马达:连接失败!
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v27/ui/image_Window_phone.py b/record_system_v27/ui/image_Window_phone.py
new file mode 100644
index 0000000..1b04e4e
--- /dev/null
+++ b/record_system_v27/ui/image_Window_phone.py
@@ -0,0 +1,868 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window_phone.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window_phone(object):
+ def setupUi(self, image_Window_phone):
+ image_Window_phone.setObjectName("image_Window_phone")
+ image_Window_phone.setEnabled(True)
+ image_Window_phone.resize(562, 1174)
+ image_Window_phone.setMouseTracking(False)
+ image_Window_phone.setAutoFillBackground(False)
+ image_Window_phone.setSizeGripEnabled(False)
+ image_Window_phone.setModal(False)
+ self.gridLayout_6 = QtWidgets.QGridLayout(image_Window_phone)
+ self.gridLayout_6.setObjectName("gridLayout_6")
+ self.frame_3 = QtWidgets.QFrame(image_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
+ self.frame_3.setSizePolicy(sizePolicy)
+ self.frame_3.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.frame_3)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.frame_7 = QtWidgets.QFrame(self.frame_3)
+ self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_7.setObjectName("frame_7")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_7)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.verticalLayout = QtWidgets.QVBoxLayout()
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.image_mode_focus_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_focus_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_focus_bt.setSizePolicy(sizePolicy)
+ self.image_mode_focus_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_focus_bt.setFont(font)
+ self.image_mode_focus_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_focus_bt.setAutoDefault(False)
+ self.image_mode_focus_bt.setObjectName("image_mode_focus_bt")
+ self.verticalLayout.addWidget(self.image_mode_focus_bt)
+ self.image_mode_exposureTime_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_exposureTime_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_exposureTime_bt.setSizePolicy(sizePolicy)
+ self.image_mode_exposureTime_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_exposureTime_bt.setFont(font)
+ self.image_mode_exposureTime_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_exposureTime_bt.setAutoDefault(False)
+ self.image_mode_exposureTime_bt.setObjectName("image_mode_exposureTime_bt")
+ self.verticalLayout.addWidget(self.image_mode_exposureTime_bt)
+ self.image_mode_dc_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_dc_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_dc_bt.setSizePolicy(sizePolicy)
+ self.image_mode_dc_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_dc_bt.setFont(font)
+ self.image_mode_dc_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_dc_bt.setAutoDefault(False)
+ self.image_mode_dc_bt.setObjectName("image_mode_dc_bt")
+ self.verticalLayout.addWidget(self.image_mode_dc_bt)
+ self.image_mode_record_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_record_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_record_bt.setSizePolicy(sizePolicy)
+ self.image_mode_record_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_record_bt.setFont(font)
+ self.image_mode_record_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_record_bt.setAutoDefault(False)
+ self.image_mode_record_bt.setObjectName("image_mode_record_bt")
+ self.verticalLayout.addWidget(self.image_mode_record_bt)
+ self.save_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.save_bt.sizePolicy().hasHeightForWidth())
+ self.save_bt.setSizePolicy(sizePolicy)
+ self.save_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.save_bt.setFont(font)
+ self.save_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.save_bt.setAutoDefault(False)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout.addWidget(self.save_bt)
+ self.gridLayout_4.addLayout(self.verticalLayout, 0, 0, 1, 1)
+ self.gridLayout_5.addWidget(self.frame_7, 0, 0, 1, 1)
+ self.frame_6 = QtWidgets.QFrame(self.frame_3)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_6)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setObjectName("gridLayout_3")
+ self.frame_10 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_10.sizePolicy().hasHeightForWidth())
+ self.frame_10.setSizePolicy(sizePolicy)
+ self.frame_10.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_10.setObjectName("frame_10")
+ self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_10)
+ self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_8.setSpacing(0)
+ self.gridLayout_8.setObjectName("gridLayout_8")
+ self.rad_dn_comboBox = QtWidgets.QComboBox(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.rad_dn_comboBox.sizePolicy().hasHeightForWidth())
+ self.rad_dn_comboBox.setSizePolicy(sizePolicy)
+ self.rad_dn_comboBox.setMinimumSize(QtCore.QSize(90, 0))
+ self.rad_dn_comboBox.setStyleSheet("/*按钮普通态*/\n"
+"QComboBox\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}")
+ self.rad_dn_comboBox.setObjectName("rad_dn_comboBox")
+ self.rad_dn_comboBox.addItem("")
+ self.rad_dn_comboBox.addItem("")
+ self.gridLayout_8.addWidget(self.rad_dn_comboBox, 0, 2, 1, 1)
+ self.framenumber_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framenumber_le.sizePolicy().hasHeightForWidth())
+ self.framenumber_le.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.framenumber_le.setFont(font)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.gridLayout_8.addWidget(self.framenumber_le, 0, 1, 1, 1)
+ self.arcus_direction_bt = QtWidgets.QPushButton(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_direction_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_direction_bt.setSizePolicy(sizePolicy)
+ self.arcus_direction_bt.setMinimumSize(QtCore.QSize(90, 0))
+ self.arcus_direction_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_direction_bt.setFont(font)
+ self.arcus_direction_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_direction_bt.setAutoDefault(False)
+ self.arcus_direction_bt.setObjectName("arcus_direction_bt")
+ self.gridLayout_8.addWidget(self.arcus_direction_bt, 0, 3, 1, 1)
+ self.label_2 = QtWidgets.QLabel(self.frame_10)
+ self.label_2.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_2.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout_8.addWidget(self.label_2, 0, 0, 1, 1)
+ self.gridLayout_3.addWidget(self.frame_10, 4, 0, 1, 1)
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.label_3 = QtWidgets.QLabel(self.frame_6)
+ self.label_3.setMinimumSize(QtCore.QSize(110, 0))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(20)
+ self.label_3.setFont(font)
+ self.label_3.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.horizontalLayout_3.addWidget(self.label_3)
+ self.framerate_le = QtWidgets.QLineEdit(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framerate_le.sizePolicy().hasHeightForWidth())
+ self.framerate_le.setSizePolicy(sizePolicy)
+ self.framerate_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.framerate_le.setFont(font)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.horizontalLayout_3.addWidget(self.framerate_le)
+ self.framenumber_recorded_label = QtWidgets.QLabel(self.frame_6)
+ self.framenumber_recorded_label.setMinimumSize(QtCore.QSize(180, 0))
+ self.framenumber_recorded_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.framenumber_recorded_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.framenumber_recorded_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.framenumber_recorded_label.setObjectName("framenumber_recorded_label")
+ self.horizontalLayout_3.addWidget(self.framenumber_recorded_label)
+ self.gridLayout_3.addLayout(self.horizontalLayout_3, 1, 0, 1, 1)
+ self.frame_9 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_9.sizePolicy().hasHeightForWidth())
+ self.frame_9.setSizePolicy(sizePolicy)
+ self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_9.setLineWidth(0)
+ self.frame_9.setObjectName("frame_9")
+ self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_9)
+ self.gridLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_7.setSpacing(0)
+ self.gridLayout_7.setObjectName("gridLayout_7")
+ self.filename_le = QtWidgets.QLineEdit(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.filename_le.sizePolicy().hasHeightForWidth())
+ self.filename_le.setSizePolicy(sizePolicy)
+ self.filename_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.filename_le.setFont(font)
+ self.filename_le.setObjectName("filename_le")
+ self.gridLayout_7.addWidget(self.filename_le, 0, 1, 1, 1)
+ self.label_6 = QtWidgets.QLabel(self.frame_9)
+ self.label_6.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_6.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_6.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_6.setObjectName("label_6")
+ self.gridLayout_7.addWidget(self.label_6, 0, 0, 1, 1)
+ self.file_number_label = QtWidgets.QLabel(self.frame_9)
+ self.file_number_label.setMinimumSize(QtCore.QSize(180, 0))
+ self.file_number_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.file_number_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.file_number_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.file_number_label.setObjectName("file_number_label")
+ self.gridLayout_7.addWidget(self.file_number_label, 0, 2, 1, 1)
+ self.gridLayout_3.addWidget(self.frame_9, 6, 0, 1, 1)
+ self.frame_5 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth())
+ self.frame_5.setSizePolicy(sizePolicy)
+ self.frame_5.setMinimumSize(QtCore.QSize(160, 0))
+ self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_5.setObjectName("frame_5")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_5)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.label_7 = QtWidgets.QLabel(self.frame_5)
+ self.label_7.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_7.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_7.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_7.setObjectName("label_7")
+ self.horizontalLayout_2.addWidget(self.label_7)
+ self.arcus_left_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_left_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_left_bt.setSizePolicy(sizePolicy)
+ self.arcus_left_bt.setMinimumSize(QtCore.QSize(50, 0))
+ self.arcus_left_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_left_bt.setFont(font)
+ self.arcus_left_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_left_bt.setAutoDefault(False)
+ self.arcus_left_bt.setObjectName("arcus_left_bt")
+ self.horizontalLayout_2.addWidget(self.arcus_left_bt)
+ self.arcus_speed_le = QtWidgets.QLineEdit(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_speed_le.sizePolicy().hasHeightForWidth())
+ self.arcus_speed_le.setSizePolicy(sizePolicy)
+ self.arcus_speed_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.arcus_speed_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.arcus_speed_le.setFont(font)
+ self.arcus_speed_le.setObjectName("arcus_speed_le")
+ self.horizontalLayout_2.addWidget(self.arcus_speed_le)
+ self.arcus_right_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_right_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_right_bt.setSizePolicy(sizePolicy)
+ self.arcus_right_bt.setMinimumSize(QtCore.QSize(50, 0))
+ self.arcus_right_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_right_bt.setFont(font)
+ self.arcus_right_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_right_bt.setAutoDefault(False)
+ self.arcus_right_bt.setObjectName("arcus_right_bt")
+ self.horizontalLayout_2.addWidget(self.arcus_right_bt)
+ self.gridLayout_3.addWidget(self.frame_5, 3, 0, 1, 1)
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ self.label_5 = QtWidgets.QLabel(self.frame_6)
+ self.label_5.setMinimumSize(QtCore.QSize(110, 0))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(20)
+ self.label_5.setFont(font)
+ self.label_5.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_5.setObjectName("label_5")
+ self.horizontalLayout_4.addWidget(self.label_5)
+ self.exposure_time_le = QtWidgets.QLineEdit(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.exposure_time_le.sizePolicy().hasHeightForWidth())
+ self.exposure_time_le.setSizePolicy(sizePolicy)
+ self.exposure_time_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.exposure_time_le.setFont(font)
+ self.exposure_time_le.setObjectName("exposure_time_le")
+ self.horizontalLayout_4.addWidget(self.exposure_time_le)
+ self.gridLayout_3.addLayout(self.horizontalLayout_4, 2, 0, 1, 1)
+ self.gridLayout_5.addWidget(self.frame_6, 0, 1, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_3, 1, 0, 1, 1)
+ self.frame_4 = QtWidgets.QFrame(image_Window_phone)
+ self.frame_4.setMinimumSize(QtCore.QSize(0, 0))
+ self.frame_4.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_4.setObjectName("frame_4")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_4)
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ spacerItem = QtWidgets.QSpacerItem(233, 12, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.t_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.t_label.sizePolicy().hasHeightForWidth())
+ self.t_label.setSizePolicy(sizePolicy)
+ self.t_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.t_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.t_label.setObjectName("t_label")
+ self.horizontalLayout.addWidget(self.t_label)
+ self.hum_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.hum_label.sizePolicy().hasHeightForWidth())
+ self.hum_label.setSizePolicy(sizePolicy)
+ self.hum_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.hum_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.horizontalLayout.addWidget(self.hum_label)
+ self.camera_status_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.camera_status_label.sizePolicy().hasHeightForWidth())
+ self.camera_status_label.setSizePolicy(sizePolicy)
+ self.camera_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.camera_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camera_status_label.setObjectName("camera_status_label")
+ self.horizontalLayout.addWidget(self.camera_status_label)
+ self.arcus_status_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_status_label.sizePolicy().hasHeightForWidth())
+ self.arcus_status_label.setSizePolicy(sizePolicy)
+ self.arcus_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.arcus_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.arcus_status_label.setObjectName("arcus_status_label")
+ self.horizontalLayout.addWidget(self.arcus_status_label)
+ self.gridLayout_6.addWidget(self.frame_4, 2, 0, 1, 1)
+ self.splitter = QtWidgets.QSplitter(image_Window_phone)
+ self.splitter.setOrientation(QtCore.Qt.Vertical)
+ self.splitter.setObjectName("splitter")
+ self.frame_2 = QtWidgets.QFrame(self.splitter)
+ self.frame_2.setFrameShape(QtWidgets.QFrame.Box)
+ self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_2.setObjectName("frame_2")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_2)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.gridLayout_2.addLayout(self.image_glo, 0, 0, 1, 1)
+ self.frame = QtWidgets.QFrame(self.splitter)
+ self.frame.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame.setFrameShape(QtWidgets.QFrame.Box)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.gridLayout = QtWidgets.QGridLayout(self.frame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.gridLayout.addLayout(self.focus_glo, 0, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.splitter, 0, 0, 1, 1)
+
+ self.retranslateUi(image_Window_phone)
+ QtCore.QMetaObject.connectSlotsByName(image_Window_phone)
+
+ def retranslateUi(self, image_Window_phone):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window_phone.setWindowTitle(_translate("image_Window_phone", "影像窗口"))
+ self.image_mode_focus_bt.setText(_translate("image_Window_phone", "调 焦"))
+ self.image_mode_exposureTime_bt.setText(_translate("image_Window_phone", "曝 光"))
+ self.image_mode_dc_bt.setText(_translate("image_Window_phone", "暗 电 流"))
+ self.image_mode_record_bt.setText(_translate("image_Window_phone", "采 集"))
+ self.save_bt.setText(_translate("image_Window_phone", "保 存"))
+ self.rad_dn_comboBox.setItemText(0, _translate("image_Window_phone", "rad"))
+ self.rad_dn_comboBox.setItemText(1, _translate("image_Window_phone", "dn"))
+ self.arcus_direction_bt.setText(_translate("image_Window_phone", "反转"))
+ self.label_2.setText(_translate("image_Window_phone", "帧 数"))
+ self.label_3.setText(_translate("image_Window_phone", "帧 率"))
+ self.framenumber_recorded_label.setText(_translate("image_Window_phone", "文件号"))
+ self.label_6.setText(_translate("image_Window_phone", "命 名"))
+ self.file_number_label.setText(_translate("image_Window_phone", "文件号"))
+ self.label_7.setText(_translate("image_Window_phone", "马 达"))
+ self.arcus_left_bt.setText(_translate("image_Window_phone", "<"))
+ self.arcus_right_bt.setText(_translate("image_Window_phone", ">"))
+ self.label_5.setText(_translate("image_Window_phone", "积分时间"))
+ self.t_label.setText(_translate("image_Window_phone", "温度:无数据"))
+ self.hum_label.setText(_translate("image_Window_phone", "湿度:无数据"))
+ self.camera_status_label.setText(_translate("image_Window_phone", "光谱仪:连接失败"))
+ self.arcus_status_label.setText(_translate("image_Window_phone", "马达:连接失败!"))
diff --git a/record_system_v27/ui/image_Window_phone.ui b/record_system_v27/ui/image_Window_phone.ui
new file mode 100644
index 0000000..72cea97
--- /dev/null
+++ b/record_system_v27/ui/image_Window_phone.ui
@@ -0,0 +1,1395 @@
+
+
+ image_Window_phone
+
+
+ true
+
+
+
+ 0
+ 0
+ 562
+ 1174
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 调 焦
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 保 存
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 90
+ 0
+
+
+
+ /*按钮普通态*/
+QComboBox
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
-
+
+ rad
+
+
+ -
+
+ dn
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 90
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 反转
+
+
+ false
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 数
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+ false
+
+
+
+ -
+
+
+
+ 180
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 命 名
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 180
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 160
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 马 达
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ <
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ >
+
+
+ false
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 积分时间
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 233
+ 12
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 马达:连接失败!
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v27/ui/spectral_Window_phone.py b/record_system_v27/ui/spectral_Window_phone.py
new file mode 100644
index 0000000..1e6c05d
--- /dev/null
+++ b/record_system_v27/ui/spectral_Window_phone.py
@@ -0,0 +1,629 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window_phone.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window_phone(object):
+ def setupUi(self, spectral_Window_phone):
+ spectral_Window_phone.setObjectName("spectral_Window_phone")
+ spectral_Window_phone.resize(540, 1175)
+ self.gridLayout_6 = QtWidgets.QGridLayout(spectral_Window_phone)
+ self.gridLayout_6.setObjectName("gridLayout_6")
+ self.frame = QtWidgets.QFrame(spectral_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+ self.frame.setSizePolicy(sizePolicy)
+ self.frame.setMinimumSize(QtCore.QSize(0, 600))
+ self.frame.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.gridLayout = QtWidgets.QGridLayout(self.frame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.spe_glo = QtWidgets.QGridLayout()
+ self.spe_glo.setObjectName("spe_glo")
+ self.gridLayout.addLayout(self.spe_glo, 0, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame, 0, 0, 1, 1)
+ self.frame_2 = QtWidgets.QFrame(spectral_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
+ self.frame_2.setSizePolicy(sizePolicy)
+ self.frame_2.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_2.setObjectName("frame_2")
+ self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_2)
+ self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_8.setSpacing(0)
+ self.gridLayout_8.setObjectName("gridLayout_8")
+ self.frame_4 = QtWidgets.QFrame(self.frame_2)
+ self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_4.setObjectName("frame_4")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_4)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setSpacing(0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.spectral_mode_autoexposure_bt = QtWidgets.QPushButton(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_autoexposure_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_autoexposure_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_autoexposure_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_autoexposure_bt.setAutoDefault(False)
+ self.spectral_mode_autoexposure_bt.setObjectName("spectral_mode_autoexposure_bt")
+ self.gridLayout_4.addWidget(self.spectral_mode_autoexposure_bt, 0, 0, 1, 1)
+ self.autoexposure_le = QtWidgets.QLineEdit(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.autoexposure_le.sizePolicy().hasHeightForWidth())
+ self.autoexposure_le.setSizePolicy(sizePolicy)
+ self.autoexposure_le.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.autoexposure_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:40pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.autoexposure_le.setObjectName("autoexposure_le")
+ self.gridLayout_4.addWidget(self.autoexposure_le, 0, 1, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_4, 0, 0, 1, 1)
+ self.frame_6 = QtWidgets.QFrame(self.frame_2)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_6)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setSpacing(0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.dc_timer_label = QtWidgets.QLabel(self.frame_6)
+ self.dc_timer_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.dc_timer_label.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.dc_timer_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.dc_timer_label.setObjectName("dc_timer_label")
+ self.gridLayout_2.addWidget(self.dc_timer_label, 0, 1, 1, 1)
+ self.spectral_mode_dc_bt = QtWidgets.QPushButton(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_dc_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_dc_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_dc_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_dc_bt.setAutoDefault(False)
+ self.spectral_mode_dc_bt.setObjectName("spectral_mode_dc_bt")
+ self.gridLayout_2.addWidget(self.spectral_mode_dc_bt, 0, 0, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_6, 1, 0, 1, 1)
+ self.frame_7 = QtWidgets.QFrame(self.frame_2)
+ self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_7.setObjectName("frame_7")
+ self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_7)
+ self.gridLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_7.setSpacing(0)
+ self.gridLayout_7.setObjectName("gridLayout_7")
+ self.spectral_mode_wb_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_wb_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_wb_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_wb_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_wb_bt.setAutoDefault(False)
+ self.spectral_mode_wb_bt.setObjectName("spectral_mode_wb_bt")
+ self.gridLayout_7.addWidget(self.spectral_mode_wb_bt, 0, 0, 1, 1)
+ self.wb_timer_label = QtWidgets.QLabel(self.frame_7)
+ self.wb_timer_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.wb_timer_label.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.wb_timer_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.wb_timer_label.setObjectName("wb_timer_label")
+ self.gridLayout_7.addWidget(self.wb_timer_label, 0, 1, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_7, 2, 0, 1, 1)
+ self.frame_5 = QtWidgets.QFrame(self.frame_2)
+ self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_5.setObjectName("frame_5")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.frame_5)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setSpacing(0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.spectral_mode_record_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_record_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_record_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_record_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_record_bt.setAutoDefault(False)
+ self.spectral_mode_record_bt.setObjectName("spectral_mode_record_bt")
+ self.gridLayout_5.addWidget(self.spectral_mode_record_bt, 0, 0, 1, 1)
+ self.data_type_comboBox = QtWidgets.QComboBox(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.data_type_comboBox.sizePolicy().hasHeightForWidth())
+ self.data_type_comboBox.setSizePolicy(sizePolicy)
+ self.data_type_comboBox.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.data_type_comboBox.setStyleSheet("/*按钮普通态*/\n"
+"QComboBox\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}")
+ self.data_type_comboBox.setFrame(False)
+ self.data_type_comboBox.setObjectName("data_type_comboBox")
+ self.data_type_comboBox.addItem("")
+ self.data_type_comboBox.addItem("")
+ self.data_type_comboBox.addItem("")
+ self.gridLayout_5.addWidget(self.data_type_comboBox, 0, 1, 1, 1)
+ self.progressBar = QtWidgets.QProgressBar(self.frame_5)
+ self.progressBar.setProperty("value", 0)
+ self.progressBar.setTextVisible(False)
+ self.progressBar.setObjectName("progressBar")
+ self.gridLayout_5.addWidget(self.progressBar, 1, 0, 1, 2)
+ self.gridLayout_8.addWidget(self.frame_5, 3, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_2, 1, 0, 1, 1)
+ self.frame_3 = QtWidgets.QFrame(spectral_Window_phone)
+ self.frame_3.setMaximumSize(QtCore.QSize(16777215, 200))
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.gridLayout_10 = QtWidgets.QGridLayout(self.frame_3)
+ self.gridLayout_10.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_10.setSpacing(0)
+ self.gridLayout_10.setObjectName("gridLayout_10")
+ self.frame_9 = QtWidgets.QFrame(self.frame_3)
+ self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_9.setObjectName("frame_9")
+ self.gridLayout_9 = QtWidgets.QGridLayout(self.frame_9)
+ self.gridLayout_9.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_9.setSpacing(0)
+ self.gridLayout_9.setObjectName("gridLayout_9")
+ self.filename_le = QtWidgets.QLineEdit(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.filename_le.sizePolicy().hasHeightForWidth())
+ self.filename_le.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(61)
+ self.filename_le.setFont(font)
+ self.filename_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:61pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.filename_le.setObjectName("filename_le")
+ self.gridLayout_9.addWidget(self.filename_le, 0, 2, 1, 1)
+ self.label_2 = QtWidgets.QLabel(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
+ self.label_2.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.label_2.setFont(font)
+ self.label_2.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout_9.addWidget(self.label_2, 0, 1, 1, 1)
+ self.file_number_label = QtWidgets.QLabel(self.frame_9)
+ self.file_number_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.file_number_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.file_number_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.file_number_label.setObjectName("file_number_label")
+ self.gridLayout_9.addWidget(self.file_number_label, 0, 3, 1, 1)
+ self.frame_10 = QtWidgets.QFrame(self.frame_9)
+ self.frame_10.setMinimumSize(QtCore.QSize(200, 0))
+ self.frame_10.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.frame_10.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_10.setObjectName("frame_10")
+ self.gridLayout_11 = QtWidgets.QGridLayout(self.frame_10)
+ self.gridLayout_11.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_11.setSpacing(0)
+ self.gridLayout_11.setObjectName("gridLayout_11")
+ self.label_3 = QtWidgets.QLabel(self.frame_10)
+ self.label_3.setMinimumSize(QtCore.QSize(140, 0))
+ self.label_3.setMaximumSize(QtCore.QSize(110, 16777215))
+ self.label_3.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.gridLayout_11.addWidget(self.label_3, 0, 0, 1, 1)
+ self.label_4 = QtWidgets.QLabel(self.frame_10)
+ self.label_4.setMinimumSize(QtCore.QSize(140, 0))
+ self.label_4.setMaximumSize(QtCore.QSize(110, 16777215))
+ self.label_4.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_4.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_4.setObjectName("label_4")
+ self.gridLayout_11.addWidget(self.label_4, 1, 0, 1, 1)
+ self.spectral_number_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_number_le.sizePolicy().hasHeightForWidth())
+ self.spectral_number_le.setSizePolicy(sizePolicy)
+ self.spectral_number_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.spectral_number_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.spectral_number_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.spectral_number_le.setObjectName("spectral_number_le")
+ self.gridLayout_11.addWidget(self.spectral_number_le, 1, 2, 1, 1)
+ self.framenumber_average_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framenumber_average_le.sizePolicy().hasHeightForWidth())
+ self.framenumber_average_le.setSizePolicy(sizePolicy)
+ self.framenumber_average_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.framenumber_average_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.framenumber_average_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.framenumber_average_le.setObjectName("framenumber_average_le")
+ self.gridLayout_11.addWidget(self.framenumber_average_le, 0, 2, 1, 1)
+ self.gridLayout_9.addWidget(self.frame_10, 0, 0, 1, 1)
+ self.gridLayout_10.addWidget(self.frame_9, 0, 0, 1, 1)
+ self.frame_8 = QtWidgets.QFrame(self.frame_3)
+ self.frame_8.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.frame_8.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_8.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_8.setObjectName("frame_8")
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_8)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setSpacing(0)
+ self.gridLayout_3.setObjectName("gridLayout_3")
+ spacerItem = QtWidgets.QSpacerItem(399, 15, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.gridLayout_3.addItem(spacerItem, 0, 0, 1, 1)
+ self.t_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.t_label.sizePolicy().hasHeightForWidth())
+ self.t_label.setSizePolicy(sizePolicy)
+ self.t_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.t_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.t_label.setObjectName("t_label")
+ self.gridLayout_3.addWidget(self.t_label, 0, 1, 1, 1)
+ self.hum_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.hum_label.sizePolicy().hasHeightForWidth())
+ self.hum_label.setSizePolicy(sizePolicy)
+ self.hum_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.hum_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.gridLayout_3.addWidget(self.hum_label, 0, 2, 1, 1)
+ self.camera_status_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.camera_status_label.sizePolicy().hasHeightForWidth())
+ self.camera_status_label.setSizePolicy(sizePolicy)
+ self.camera_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.camera_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camera_status_label.setObjectName("camera_status_label")
+ self.gridLayout_3.addWidget(self.camera_status_label, 0, 3, 1, 1)
+ self.gridLayout_10.addWidget(self.frame_8, 1, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_3, 2, 0, 1, 1)
+
+ self.retranslateUi(spectral_Window_phone)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window_phone)
+
+ def retranslateUi(self, spectral_Window_phone):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window_phone.setWindowTitle(_translate("spectral_Window_phone", "光谱窗口"))
+ self.spectral_mode_autoexposure_bt.setText(_translate("spectral_Window_phone", "曝 光"))
+ self.dc_timer_label.setText(_translate("spectral_Window_phone", "计时"))
+ self.spectral_mode_dc_bt.setText(_translate("spectral_Window_phone", "暗 电 流"))
+ self.spectral_mode_wb_bt.setText(_translate("spectral_Window_phone", "白 板"))
+ self.wb_timer_label.setText(_translate("spectral_Window_phone", "计时"))
+ self.spectral_mode_record_bt.setText(_translate("spectral_Window_phone", "采 集"))
+ self.data_type_comboBox.setCurrentText(_translate("spectral_Window_phone", "Ref"))
+ self.data_type_comboBox.setItemText(0, _translate("spectral_Window_phone", "Ref"))
+ self.data_type_comboBox.setItemText(1, _translate("spectral_Window_phone", "DN"))
+ self.data_type_comboBox.setItemText(2, _translate("spectral_Window_phone", "Rad"))
+ self.label_2.setText(_translate("spectral_Window_phone", "文 件"))
+ self.file_number_label.setText(_translate("spectral_Window_phone", "文件号"))
+ self.label_3.setText(_translate("spectral_Window_phone", "自动平均"))
+ self.label_4.setText(_translate("spectral_Window_phone", "连续测量"))
+ self.t_label.setText(_translate("spectral_Window_phone", "温度:无数据"))
+ self.hum_label.setText(_translate("spectral_Window_phone", "湿度:无数据"))
+ self.camera_status_label.setText(_translate("spectral_Window_phone", "光谱仪:连接失败"))
diff --git a/record_system_v27/ui/spectral_Window_phone.ui b/record_system_v27/ui/spectral_Window_phone.ui
new file mode 100644
index 0000000..7962cf0
--- /dev/null
+++ b/record_system_v27/ui/spectral_Window_phone.ui
@@ -0,0 +1,1057 @@
+
+
+ spectral_Window_phone
+
+
+
+ 0
+ 0
+ 540
+ 1175
+
+
+
+ 光谱窗口
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 600
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:40pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 计时
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 白 板
+
+
+ false
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 计时
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QComboBox
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
+ Ref
+
+
+ false
+
+
-
+
+ Ref
+
+
+ -
+
+ DN
+
+
+ -
+
+ Rad
+
+
+
+
+ -
+
+
+ 0
+
+
+ false
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 200
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Microsoft Yahei
+ 61
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:61pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文 件
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 200
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 140
+ 0
+
+
+
+
+ 110
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 自动平均
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 140
+ 0
+
+
+
+
+ 110
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 连续测量
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 399
+ 15
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v28/2record_system_v28.py b/record_system_v28/2record_system_v28.py
new file mode 100644
index 0000000..bf9d108
--- /dev/null
+++ b/record_system_v28/2record_system_v28.py
@@ -0,0 +1,2313 @@
+# -*- coding:utf-8 -*-
+
+'''
+在2record system_v2.2的基础上更新:
+1、光谱模式像asd一样,不停的采集和显示,但是不保存,点击保存按钮时才保存光谱
+2、
+3、
+4、
+5、
+6、
+7、
+'''
+
+# 内置包
+import os, sys, functools, re, shutil, traceback, time
+import subprocess
+import datetime # 几种Python执行时间的计算方法:https://blog.csdn.net/wangshuang1631/article/details/54286551
+import logging
+
+# 三方包
+import numpy as np
+from ximea import xiapi
+import serial
+import serial.tools.list_ports
+from serial.serialutil import SerialBase, SerialException
+
+# 界面包
+from PyQt5.QtCore import Qt, QObject, QThreadPool, QTimer, QRegExp, pyqtSignal
+# from PyQt5.QtCore import QRectF, pyqtSignal, QRunnable, pyqtSlot, QT_VERSION_STR
+from PyQt5.QtGui import QIntValidator, QRegExpValidator, QPixmap, QImage, QPainterPath
+from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox, qApp, QDialog, QFileDialog, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem
+
+import matplotlib
+matplotlib.use("Qt5Agg") # 声明使用QT5
+from library.matplotlib_display_image_spectral import MatplotlibSpectralViewer, MatplotlibImageViewer
+
+
+# 自己写的包
+from QtImageViewer import QtImageViewer
+from QtSpectralViewer import QtSpectralViewer
+from library.multithread import Worker
+from library.image_reader_writer import ImageReaderWriter
+from library.functions import get_path, get_resource_path, return_file_path
+from library.message_box import MessageBox
+from library.config import ConfigFile
+from library.log import Log
+
+# Qtdesigner所画界面
+from record_system_v28.ui.enter_window import *
+from record_system_v28.ui.image_Window_phone import *
+from record_system_v28.ui.spectral_Window_phone import *
+
+
+# 主窗口
+class EnterWindow(QMainWindow, Ui_enter_Window):
+ def __init__(self, camera, parent=None):
+ super(EnterWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+
+ self.image_mode_phone_bt.clicked.connect(self.image_window)
+
+ self.spectral_mode_bt.clicked.connect(self.spectral_window)
+
+ # self.setEnabled(False) # 先设置本窗口不可用,当打开相机成功后,才设置为可用
+
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ def image_window(self):
+ self.image_window_phone_instance = ImageWindowPhone()
+ self.image_window_phone_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.image_window_phone_instance.show()
+
+ def spectral_window(self):
+ self.spectral_window_instance = SpectralWindow()
+ print(id(self.spectral_window_instance))
+ self.spectral_window_instance.setWindowFlags(Qt.WindowMinMaxButtonsHint | Qt.WindowCloseButtonHint)
+ self.spectral_window_instance.show()
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ self.camstatus_label.setText('相机打开成功!')
+
+ # 如果相机打开成功,界面中label颜色设置为绿色
+ self.change_lable_background_color('green')
+
+ self.setEnabled(True) # 如果相机打开成功,则窗口可用
+ elif imager_status == 1001:
+ self.camstatus_label.setText('相机打开时出现不是ximea错误的未知错误!')
+
+ # 如果相机打开成功,界面中label颜色设置为绿色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 1:
+ self.camstatus_label.setText('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ self.camstatus_label.setText('没有检测到光谱仪!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 57:
+ self.camstatus_label.setText('相机被占用,请关机重启!')
+
+ # 如果相机打开失败,界面中label颜色设置为红色
+ self.change_lable_background_color('red')
+
+ self.setEnabled(False) # 如果相机打开失败,则窗口不可用
+ elif imager_status == 103:
+ pass
+
+ def change_lable_background_color(self, color):
+ pattern = re.compile('background-color:rgb[(](.*)[)]')
+ old_style_sheet = self.camstatus_label.styleSheet()
+
+ if color == 'red': # 如果相机打开失败,界面中label颜色设置为红色
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0)', old_style_sheet)
+ self.camstatus_label.setStyleSheet(new_style_sheet)
+ elif color == 'green': # 如果相机打开成功,界面中label颜色设置为绿色
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0)', old_style_sheet)
+ self.camstatus_label.setStyleSheet(new_style_sheet)
+
+
+class SerialPort(QObject):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ serial_signal = pyqtSignal(object) # 建立信号,用于发射获取的温湿度
+
+ def __init__(self):
+ super(SerialPort, self).__init__()
+
+ # 建立进程池:https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 获取log温度日志的文件夹
+ self.config_file_object = ConfigFile()
+
+ # log
+ self.logger = logging.getLogger('root.serial')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//temperature.log'):
+ with open(self.config_file_object.log_dir + '//temperature.log', 'w') as f:
+ pass
+
+ formatter1 = logging.Formatter('%(asctime)s %(message)s')
+ temperature_file_handler = logging.FileHandler(self.config_file_object.log_dir + '//temperature.log') # 输出到文件
+ temperature_file_handler.setLevel(logging.DEBUG)
+ temperature_file_handler.setFormatter(formatter1)
+
+ self.logger.addHandler(temperature_file_handler)
+
+ self.connect_number = 0 # 记录打开串口的次数
+ self.serial_port = self.open_serial_port()
+
+ self.timer = QTimer()
+ self.timer.timeout.connect(self.receiver_data_from_port)
+ # self.timer.start(1000)
+
+ self.receiver_data_from_port_wraper()
+
+ def open_serial_port(self):
+ self.connect_number += 1
+ port_list = list(serial.tools.list_ports.comports()) # 列出所有可用串口
+ # print(port_list)
+
+ if len(port_list) > 0: # 如果可用串口 >0 个
+ # 打印出所有串口的信息
+ for i in range(0, len(port_list)):
+ print(port_list[i])
+
+ # 打开第一个串口
+ ser = serial.Serial(port_list[0].device)
+ # print('温湿度传感器打开成功!')
+ return ser
+ elif len(port_list) == 0: # 如果可用串口为0个
+ if self.connect_number == 1:
+ self.logger.info('无可用串口,温湿度传感器不可用!')
+ else:
+ self.logger.error('串口连接上之后,断开连接!')
+ return 1 # 如果返回1,则代表没有可用串口;通过1来判断不执行定时器触发:self.timer.start(1000)
+ else: # 其他没有考虑到的情况
+ return 1
+
+ def receiver_data_from_port_wraper(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.receiver_data_from_port)
+
+ self.threadpool.start(worker)
+
+ def receiver_data_from_port(self):
+ '''
+ 定时器QTimer没隔1s调用此函数一次 → 让串口buffer有足够的数据等待读取
+ :return: 无返回值
+
+ 本函数功能:1、串口中接收字节数据,有两种帧 → 代表两种数据
+ 2、判断帧头位置和本帧数据类型
+ 3、判断帧尾 → 等效判断本帧数据是否完全
+ 4、如果数据帧完整 → 解析数据,将温度湿度显示到界面上和写入到文件中
+ '''
+ while True:
+ try:
+ if self.serial_port.in_waiting: # 如果串口buffer有数据等待读取
+ bytes_receive = self.serial_port.read(self.serial_port.inWaiting()) # 读取串口buffer的数据
+ # print(len(bytes_receive))
+
+ # 判断帧头位置,通过正则表达式
+ hex_receive = bytes_receive.hex() # 一个字节需要一个两位16进制数表示,所以:len(hex_receive) = len(bytes_receive) / 2
+ p = re.compile('5a5a*')
+ index_head = [i.start() / 2 for i in re.finditer(p, hex_receive)] # re.finditer()
+ # print(hex_receive)
+ # print(index_head)
+ except SerialException: # 程序打开时,温湿度传感器的串口工作正常;如果程序运行中拔掉串口就会出现此异常
+ self.logger.error('在程序运行中温湿度传感器的串口出现问题!')
+
+ # 再次尝试打开串口
+ self.serial_port = self.open_serial_port()
+ if not isinstance(self.serial_port, int):
+ self.logger.info('再次尝试连接温湿度传感器成功!')
+ else:
+ self.logger.info('再次尝试连接温湿度传感器失败!')
+ except AttributeError: # int object has no attribute: in_waiting
+ self.timer.stop()
+ # self.logger.info('停止定时触发器!')
+ except Exception as e: # 未出现过的异常。当第一次出现时,需要编写代码处理,先写入日志文件(log)
+ self.logger.critical('未知错误!')
+ else: # 当没有捕获到异常时,代表串口数据获取成功 → 执行数据解析
+ # 解析数据
+ try:
+ if len(index_head) != 0:
+ Lux = 1.0
+ T = 1.0
+ P = 1.0
+ Hum = 1.0
+ H = 1.0
+ Lux_full = 0 # 判断光照帧的数据是否完整。0:不完整;1:完整;
+ T_full = 0 # 判断温度帧的数据是否完整。0:不完整;1:完整;
+ try:
+ for i in index_head: # 循环遍历每个帧头
+ if bytes_receive[int(i) + 2] == 21: # 0x15=21,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 8]) & 0xff == bytes_receive[int(i) + 8]: # 判断帧尾是否正确
+ # print('光照帧的帧尾正确!')
+
+ Lux_full = 1 # 如果帧尾,此帧数据数完整的
+ Lux = ((bytes_receive[int(i) + 4] << 24) | (bytes_receive[int(i) + 5] << 16) | (
+ bytes_receive[int(i) + 6] << 8) | bytes_receive[int(i) + 7]) / 100
+ if bytes_receive[int(i) + 2] == 69: # 0x45=69,判断帧头类型
+ if sum(bytes_receive[int(i):int(i) + 14]) & 0xff == bytes_receive[int(i) + 14]: # 判断帧尾是否正确
+ # print('温度帧的帧尾正确!')
+
+ T_full = 1 # 当执行这段代码时,代表帧头帧尾都正常,此帧数据数完整的
+ T = ((bytes_receive[int(i) + 4] << 8) | bytes_receive[int(i) + 5]) / 100
+ P = ((bytes_receive[int(i) + 6] << 24) | (bytes_receive[int(i) + 7] << 16) | (
+ bytes_receive[int(i) + 8] << 8) | bytes_receive[
+ int(i) + 9]) / 100
+ Hum = ((bytes_receive[int(i) + 10] << 8) | bytes_receive[int(i) + 11]) / 100
+ H = ((bytes_receive[int(i) + 12] << 8) | bytes_receive[int(i) + 13]) / 100
+ except IndexError as e: # 当出现帧头,但是帧头到帧尾的数据不全 → 在判断帧尾是否正确时就会出现索引越界
+ # print('----------------------索引越界!')
+ pass
+ except Exception: # 当出现前面没有解决的异常时,前面的异常捕捉就失效。最后通过异常基类来捕捉 → 代表需要修改代码进行处理的新异常
+ # print('---------------------------------没遇见过的异常')
+ pass
+
+ # 将数据显示和写入文件
+ if Lux_full + T_full == 2: # x + y == 2代表温度帧和光照帧都完整
+ # self.t_label.setVisible(True)
+ # self.hum_label.setVisible(True)
+ # self.t_label.setText('温度:' + str(T))
+ # self.hum_label.setText('湿度:' + str(Hum))
+
+ # print('发送数据')
+
+ self.serial_signal.emit((str(T), str(Hum)))
+ self.logger.debug('%s %s %s', str(T), str(Hum), str(camera.get_temp())) # 将温湿度记录进log文件中
+
+ # print('光照强度:%f' % Lux)
+ # print('温度:%f' % T)
+ # print('气压:%f' % P)
+ # print('湿度:%f' % Hum)
+ # print('海拔:%f' % H)
+ # print()
+ elif Lux_full + T_full == 1:
+ # print('只有一个数据帧是完整的。(光照帧或者温度帧)')
+ # print()
+ pass
+ except UnboundLocalError:
+ # print(2222222222222222222222222222222)
+ # traceback.print_exc()
+ pass
+ except Exception:
+ self.logger.critical('未知错误!')
+ finally: # 不管有没有捕获到异常都会执行,一般用作资源回收
+ pass
+
+ time.sleep(3)
+
+
+# 图像窗口
+class ImageWindowPhone(QDialog, Ui_image_Window_phone):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ arcus_status_signal = pyqtSignal(int) # arcus信号:0→马达未连接;1→马达连接成功;
+ plot_signal = pyqtSignal() # 采集影像时,边采集边刷新显示
+
+ def __init__(self, parent=None):
+ '''
+ The super().__init__() method invokes the base class constructor from the MyForm class,
+ that is, the constructor of the QDialog class is invoked from MyForm class to indicate that
+ QDialog is displayed through this class iss a top-level window.
+ '''
+ super(ImageWindowPhone, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:此行代码必须放在show()函数之前
+
+ # 配置文件读取和写入类,配置文件读写和界面分离
+ # 1、采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取
+ # 2、并保存在此类中
+ self.config_file_object = ConfigFile()
+
+ # log
+ self.logger = logging.getLogger('root.image_phone')
+
+ if not os.path.exists(self.config_file_object.log_dir + '//image_operate.log'):
+ with open(self.config_file_object.log_dir + '//image_operate.log', 'w') as f:
+ pass
+
+ image_operate_file_handler = logging.FileHandler(self.config_file_object.log_dir + "//image_operate.log") # 输出到文件
+ image_operate_file_handler.setLevel(logging.INFO)
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ image_operate_file_handler.setFormatter(formatter)
+
+ stream_handler = logging.StreamHandler() # 输出到控制台
+ stream_handler.setLevel(logging.DEBUG)
+ stream_handler.setFormatter(formatter)
+ self.logger.addHandler(image_operate_file_handler)
+ self.logger.addHandler(stream_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.serial_signal.connect(self.update_temperature)
+ self.hpi_temperature = None # 暂时保存温度,当保存影像文件时会用到
+
+ # 数据采集保存类,采集数据并将数据保存在此类中,数据采集和界面分离
+ self.image_camera_operation = CameraOperation(self.hpi_temperature, self.config_file_object)
+
+ # 当配置文件读取完成后,就第一时间根据读取的配置文件设置相机曝光、帧率和gain
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+ self.initiate_arcus_speed() # 初始化arcus速度
+ self.set_arcus_speed_bool = True # 当马达断开后设置为False,再次连接时通过False设置马达速度
+
+ # 采集影像时,边采集边刷新显示
+ self.plot_signal.connect(self.plotimg)
+ self.plot_when_record_finished_boot = False # 当点击停止采集按钮时,绘制整个采集到的影像
+
+ # 建立进程池:https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 初始化窗口中的值
+ self.framenumber_le.setText(str(self.config_file_object.frame_number))
+ self.framerate_le.setText(str(self.config_file_object.framerate))
+ self.exposure_time_le.setText(str(self.config_file_object.exposure_time))
+ self.arcus_speed_le.setText(str(self.config_file_object.arcus_speed))
+ self.filename_le.setText(self.config_file_object.default_image_name)
+
+ # 显示影像和调焦
+ # self.myImageFigure = MatplotlibImageViewer()
+ self.myImageFigure = QtImageViewer()
+ self.myImageFigure.leftMouseButtonPressed.connect(self.handle_left_click)
+ self.image_glo.addWidget(self.myImageFigure)
+
+ # self.myFocusFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)')
+ self.myFocusFigure = QtSpectralViewer()
+ self.focus_glo.addWidget(self.myFocusFigure)
+
+ # 操作光谱仪
+ self.state = 0 # 光谱仪操作状态:曝光=1;暗电流=3;→ 所以只有state==4时才能开始采集影像
+ self.focus_count = 1 # 用于调焦按钮点击计数,取2的余数;当余数为1是执行调焦,当余数为0时停止调焦
+ self.record_count = 1 # 用于采集按钮点击计数,取2的余数;当余数为1是执行采集,当余数为0时停止采集;这是为了使用通过一个按钮控制开始采集和停止采集
+
+ self.image_mode_exposureTime_bt.clicked.connect(self.run)
+ self.image_mode_focus_bt.clicked.connect(self.run) # 停止调焦操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_mode_dc_bt.clicked.connect(self.run)
+ self.image_mode_record_bt.clicked.connect(self.run) # 停止采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.save_bt.clicked.connect(self.run)
+
+ # 手动改变窗口中的值,然后将值写入camera_operation类对应的变量中
+ self.exposure_time_le.setValidator(QIntValidator()) # QIntValidator是一个类
+ self.framerate_le.setValidator(QIntValidator())
+ self.framenumber_le.setValidator(QIntValidator())
+
+ my_regex = QRegExp("[a-zA-Z0-9]*")
+ my_validator = QRegExpValidator(my_regex, self.filename_le)
+ self.filename_le.setValidator(my_validator)
+
+ self.exposure_time_le.editingFinished.connect(self.text_edited)
+ # self.exposure_time_le.setPlaceholderText('曝光时间')
+ self.framerate_le.editingFinished.connect(self.text_edited)
+ self.framenumber_le.editingFinished.connect(self.text_edited)
+ self.filename_le.editingFinished.connect(self.text_edited)
+
+ # 马达相关操作
+ self.arcus_left_bt.pressed.connect(self.leftMove)
+ self.arcus_left_bt.released.connect(self.stop)
+ self.arcus_right_bt.pressed.connect(self.rightMove)
+ self.arcus_right_bt.released.connect(self.stop)
+
+ # self.arcus_speed_le.setText(self.arc.write('HSPD'))
+ self.arcus_speed_le.editingFinished.connect(self.text_edited)
+ self.arcus_speed_le.setValidator(QIntValidator())
+
+ self.time = time.time() # 控制arcus两次命令发送的时间间隔
+ self.time_interval = 1
+
+ system_setting.camera_status_signal.connect(self.response_to_imager_status)
+
+ # 检测arcus马达的连接情况
+ self.timer = QTimer(self) # 使用这个定时器,会造成界面卡顿
+ self.timer.timeout.connect(self.test_arcus_status)
+ # self.timer.start(5000)
+
+ self.test_arcus_status_wraper()
+ self.arcus_status_signal.connect(self.response_to_arcus_status)
+
+ # 1)决定采集DN/red;2)反转马达
+ self.rad_dn_comboBox.currentIndexChanged.connect(self.change_rad_dn)
+ self.arcus_direction_bt.clicked.connect(self.change_arcus_direction)
+
+ def change_rad_dn(self):
+ if self.rad_dn_comboBox.currentText() == 'rad':
+ self.image_camera_operation.record_rad_bool = True
+ elif self.rad_dn_comboBox.currentText() == 'dn':
+ self.image_camera_operation.record_rad_bool = False
+
+ def change_arcus_direction(self):
+ if self.image_camera_operation.arcus_reverse_while_record == False:
+ self.image_camera_operation.arcus_reverse_while_record = True
+ self.change_widget_background_color(self.arcus_direction_bt, 'red')
+ elif self.image_camera_operation.arcus_reverse_while_record == True:
+ self.image_camera_operation.arcus_reverse_while_record = False
+ self.change_widget_background_color(self.arcus_direction_bt, 'gray')
+
+ def test_arcus_status_wraper(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.test_arcus_status)
+
+ self.threadpool.start(worker)
+
+ def test_arcus_status(self):
+ while True:
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' DN'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+ if 'Arcus device connected' in output.decode('utf-8'):
+ self.arcus_status_signal.emit(1)
+
+ if not self.set_arcus_speed_bool: # 当马达断开再次连接时,需要重新设置速度
+ python2_set_arcus_speed_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' HSPD=' + str(self.config_file_object.arcus_speed)
+ python2_set_arcus_speed_process = subprocess.Popen(python2_set_arcus_speed_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ python2_set_arcus_speed_output, python2_set_arcus_speed_error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ python2_set_arcus_speed_process.kill()
+ python2_set_arcus_speed_output, python2_set_arcus_speed_error = process.communicate()
+
+ self.set_arcus_speed_bool = True
+ elif 'No arcus devices' in output.decode('utf-8') or 'Cannot connect Arcus device' in output.decode('utf-8'):
+ self.arcus_status_signal.emit(0)
+ self.set_arcus_speed_bool = False
+ except subprocess.TimeoutExpired:
+ process.kill()
+ # output2, error2 = process.communicate()
+ # if 'Arcus device connected' in output2.decode('utf-8'):
+ # self.arcus_status_signal.emit(1)
+ # elif 'No arcus devices' in output2.decode('utf-8'):
+ # self.arcus_status_signal.emit(0)
+ # self.set_arcus_speed_bool = False
+
+ time.sleep(4) # 本线程沉睡3秒
+
+ def response_to_arcus_status(self, arcus_status):
+ if arcus_status == 0:
+ self.arcus_status_label.setText('马达:连接失败!')
+ self.change_widget_background_color(self.arcus_status_label, 'red')
+ elif arcus_status == 1:
+ self.arcus_status_label.setText('马达:连接正常!')
+ self.change_widget_background_color(self.arcus_status_label, 'green')
+
+ def response_to_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ # print('相机打开成功!')
+
+ try:
+ temperature = camera.get_temp()
+ except Exception:
+ temperature = None
+
+ self.camera_status_label.setText('光谱仪:' + str(temperature))
+
+ self.change_widget_background_color(self.camera_status_label, 'green')
+ elif imager_status == 1001:
+ print('相机打开时出现不是ximea错误的未知错误!')
+ elif imager_status == 1:
+ # print('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ self.camera_status_label.setText('光谱仪:断开连接')
+ self.change_widget_background_color(self.camera_status_label, 'red')
+
+ self.setEnabled(False)
+ self.close()
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ print('没有检测到光谱仪!')
+ elif imager_status == 103:
+ pass
+
+ def leftMove(self):
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J-'
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' CLR EO=1 J-'
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+
+ # # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ # while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ # process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ # output, error = process.communicate(timeout=2)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ def rightMove(self):
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py CLR EO=1 J+'
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' CLR EO=1 J+'
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+
+ # # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ # while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ # process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ # output, error = process.communicate(timeout=2)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ def stop(self):
+ self.time = time.time()
+
+ # python2_command = r'D:\software\Anaconda3\envs\py27_32\python.exe D:\py27_program\arcus\ArcusDevice.py STOP'
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' STOP'
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=2)
+
+ # # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ # while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ # process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ # output, error = process.communicate(timeout=2)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ def handle_left_click(self, x, y):
+ # 画出光谱
+ try:
+ row = int(y)
+ column = int(x)
+ # print("Pixel (row=" + str(row) + ", column=" + str(column) + ")")
+
+ _, _, img = ImageReaderWriter.read_img('corning410_test', column, row, 1, 1)
+
+ if isinstance(img, np.ndarray): # 如果点击到图像之外,img就是NoneType,就不重画光谱
+ # print('点击有效')
+
+ self.myFocusFigure.plot_wrap(self.image_camera_operation.get_wavelength_object.wave(model='array'), img[:, 0, 0])
+ except TypeError:
+ pass
+ # print('有错')
+ # self.logger.critical('TypeError:', exc_info=True)
+ except Exception:
+ self.logger.critical('点击显示光谱时出现未知错误:', exc_info=True)
+ traceback.print_exc()
+
+ # 手动修改界面中的值后,为相机重新设置如下参数:exposure, gain, framerate
+ def text_edited(self):
+ try:
+ # 将改变值1)保存到配置文件对象,供程序运行使用2)写入到配置文件,供程序下次打开读取
+ self.config_file_object.image_signal.emit(
+ {'exposure_time': int(float(self.exposure_time_le.text())),
+ 'framerate': int(float(self.framerate_le.text())), 'frame_number': int(float(self.framenumber_le.text())),
+ 'default_image_name': self.filename_le.text(), 'arcus_speed': self.arcus_speed_le.text()})
+ except ValueError:
+ self.x = MessageBox('请输入正确的值!')
+ self.x.exec()
+ except Exception:
+ self.logger.critical('设置曝光/gain/帧率/帧数时出现未知错误!', exe_info=True)
+
+ if self.sender().objectName() == 'exposure_time_le':
+ self.state = 1 # 手动改变曝光时间后,强制让用户重新采集暗电流+白板
+
+ print('exposure_time_le改变')
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if self.sender().objectName() == 'framerate_le':
+ self.state = 0 # 改变帧率后,需要重新曝光
+
+ print('framerate_le改变')
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if self.sender().objectName() == 'framenumber_le':
+ self.image_camera_operation.create_rgb()
+
+ if self.sender().objectName() == 'arcus_speed_le':
+ time_now = time.time()
+ if time_now - self.time > self.time_interval:
+ self.time = time.time()
+
+ python2_command = r'python2.exe ' + get_resource_path('./data/ArcusDevice.py') + ' HSPD=' + str(self.arcus_speed_le.text())
+
+ try:
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=1)
+
+ # test_arcus_status函数不停的执行命令(DN),检测马达连接情况;当在检测的同时执行移动马达命令,就会出现:Cannot connect Arcus device
+ while 'Cannot connect Arcus device' in output.decode('utf-8'):
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+
+ print('改变arcus速度出错output', output)
+ print('改变arcus速度出错error', error)
+
+ def initiate_arcus_speed(self):
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' HSPD=' + str(self.config_file_object.arcus_speed)
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=1)
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output, error = process.communicate()
+
+ def update_temperature(self, data):
+ try:
+ self.hpi_temperature = data[0]
+
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+
+ self.change_widget_background_color(self.t_label, 'green')
+ self.change_widget_background_color(self.hum_label, 'green')
+ except:
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ def timer_start(self):
+ '''
+ 本函数目的是在self.timer.start(1000)外包裹一层(有点装饰器的感觉),加入判断:
+ 1、如果self.serial_port为串口类型,就触发定时器self.timer.start(1000)
+ 2、如果self.serial_port == 1(为int类型),则代表硬件中没有温湿度传感器,就没必要触发定时器self.timer.start(1000)
+ :return: 无返回值
+ '''
+
+ if isinstance(self.serial_port, serial.serialwin32.Serial):
+ self.timer.start(1000)
+ elif isinstance(self.serial_port, int):
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ else:
+ pass
+
+ def plotimg(self):
+ try:
+ if self.qt_sender == 'image_mode_record_bt':
+ frame_number_to_plot = self.image_camera_operation.record_time_for_plot * self.config_file_object.framerate
+
+ self.framenumber_recorded_label.setText(str(frame_number_to_plot))
+
+ if frame_number_to_plot < 1000 or frame_number_to_plot == self.config_file_object.frame_number or self.plot_when_record_finished_boot: # 当采集的帧数大于1200帧时,为了防止界面卡死,就停止画图
+ self.img = np.dstack((self.image_camera_operation.rgb[2, 0:frame_number_to_plot, :], self.image_camera_operation.rgb[1, 0:frame_number_to_plot, :],
+ self.image_camera_operation.rgb[0, 0:frame_number_to_plot, :]))
+
+ self.myImageFigure.setImage(self.img)
+
+ self.plot_when_record_finished_boot = False
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.myImageFigure.setImage(self.image_camera_operation.image_container)
+
+ n = int(self.image_camera_operation.image_container.shape[0] / 2)
+ self.myFocusFigure.plot_wrap(self.image_camera_operation.image_container[n, :])
+
+ # worker = Worker(self.myImageFigure.setImage, self.image_camera_operation.image_container)
+ # self.threadpool.start(worker)
+ except:
+ self.logger.critical('未知错误--界面中绘制影像和光谱时!\n%s', exc_info=True)
+
+ # 调焦、采集暗电流、采集白板、采集影像 都通过此函数
+ def run(self):
+ try:
+ self.qt_sender = self.sender().objectName()
+
+ if self.qt_sender == 'image_mode_focus_bt':
+ if self.focus_count % 2 == 1:
+ self.image_mode_focus_bt.setText('停止调焦')
+ self.core_operation()
+ self.focus_count += 1
+
+ self.change_widget_background_color(self.image_mode_focus_bt, 'red')
+ elif self.focus_count % 2 == 0: # 停止调焦操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.image_camera_operation.focus = False
+ self.image_mode_focus_bt.setText('调焦')
+ self.focus_count += 1
+ elif self.qt_sender == 'image_mode_exposureTime_bt':
+ self.state = 1
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_exposureTime_bt, 'red')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ self.x.exec()
+ elif self.state == 1 or self.state == 4: # 正常采集暗电流
+ self.x = MessageBox('请先确认镜头盖已安装!')
+ self.x.exec()
+
+ self.state = 4
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_dc_bt, 'red')
+ elif self.qt_sender == 'image_mode_record_bt':
+ if self.record_count % 2 == 1:
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ self.x.exec()
+ elif self.state == 1: #
+ self.x = MessageBox('请采集暗电流!')
+ self.x.exec()
+ elif self.state == 4: # 正常采集影像,采集DN/反射率的判断 放在CameraOperation类中
+ self.record_count += 1
+ self.image_mode_record_bt.setText('停止采集')
+
+ self.core_operation()
+
+ self.change_widget_background_color(self.image_mode_record_bt, 'red')
+ elif self.record_count % 2 == 0: # 停止采集操作非常简单,耗时非常短,瞬间可回到event loop,不会使界面卡死;所以不需要多线程
+ self.plot_when_record_finished_boot = True
+ self.plot_signal.emit()
+
+ self.image_camera_operation.record = False
+ self.image_mode_record_bt.setText('采集')
+ elif self.qt_sender == 'save_bt':
+ worker = Worker(self.savedata)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+
+ self.threadpool.start(worker)
+
+ self.change_widget_background_color(self.save_bt, 'red')
+ except Exception:
+ traceback.print_exc()
+
+ # 改变按钮三态中普通态的背景颜色
+ def change_widget_background_color(self, qt_widget, color):
+ pattern = re.compile('background-color(.*)(normal\*/)')
+ old_style_sheet = qt_widget.styleSheet()
+
+ if color == 'red':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'green':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'gray':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(225 , 225 , 225);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+
+ def core_operation(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.image_camera_operation.start_AcquireData, camera, self.qt_sender, self.plot_signal)
+
+ worker.signals.error.connect(self.operate_failed)
+ worker.signals.finished.connect(self.operate_success)
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ '''
+ 曝光参数的设置过程:
+ (1)曝光参数返回到界面中的QLineEdit;
+ (2)通过QLineEdit的textChanged事件将值写入到camera_operation对应的变量;
+ (3)为相机设置参数:1)通过worker的finished信号【本程序使用】2)也可以通过QLineEdit的textChanged事件调用self.set_exposure函数,为相机设置参数
+ 这种过程的好处是界面显示的曝光参数和实际设置的是同步的
+ '''
+ worker.signals.result.connect(self.post_auto_expose)
+
+ self.threadpool.start(worker)
+
+ self.disable_bt(True)
+
+ def disable_bt(self, bool):
+ # 两个if判断存在的原因:调焦/停止调焦(采集/停止采集)使用同一个按钮,所以不能将其设置为不可用
+ if self.qt_sender !='image_mode_focus_bt':
+ self.image_mode_focus_bt.setDisabled(bool)
+ if self.qt_sender != 'image_mode_record_bt':
+ self.image_mode_record_bt.setDisabled(bool)
+
+ if bool == False: # 操作完成后设置为可用
+ self.image_mode_record_bt.setDisabled(bool)
+ self.image_mode_focus_bt.setDisabled(bool)
+
+ self.image_mode_exposureTime_bt.setDisabled(bool)
+ self.image_mode_dc_bt.setDisabled(bool)
+ self.save_bt.setDisabled(bool)
+ self.arcus_left_bt.setDisabled(bool)
+ self.arcus_right_bt.setDisabled(bool)
+
+ self.exposure_time_le.setDisabled(bool)
+ self.framerate_le.setDisabled(bool)
+ self.arcus_speed_le.setDisabled(bool)
+ self.framenumber_le.setDisabled(bool)
+ self.filename_le.setDisabled(bool)
+
+ self.rad_dn_comboBox.setDisabled(bool)
+ self.arcus_direction_bt.setDisabled(bool)
+
+ def operate_failed(self, traceback_info):
+ if traceback_info[0] == xiapi.Xi_error:
+ if traceback_info[1].status == 1: # 在ximea的API中代表"Invalid handle":相机断开连接
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.error('自动曝光失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.error('调焦失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.error('采集暗电流失败:相机断开连接!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.error('采集影像失败:相机断开连接!\n%s', traceback_info[2])
+ elif traceback_info[1].status == 56: # 在ximea的API中代表"No Devices Found":在执行cam.open_device()时,无相机打开
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.error('自动曝光失败:无相机可供打开!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.error('调焦失败:无相机可供打开!\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.error('采集暗电流失败:无相机可供打开\n%s', traceback_info[2])
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.error('采集影像失败:无相机可供打开\n%s', traceback_info[2])
+ elif traceback_info[1].status == 12: # 在ximea的API中代表"Not supported":当相机正在采集数据时,执行代码cam.set_imgdataformat('XI_RAW16')
+ pass
+ elif traceback_info[1].status == 41: # 在ximea的API中代表"Acquisition already started":相机已经开始采集数据
+ pass
+ elif traceback_info[0] == ValueError:
+ if self.qt_sender == 'save_bt':
+ self.logger.error('保存影像失败--影像名不正确!\n%s', traceback_info[2])
+
+ self.x = MessageBox('请输入正确的影像名!')
+ self.x.exec()
+ elif traceback_info[0] == FileNotFoundError:
+ if self.qt_sender == 'save_bt':
+ self.logger.error('保存影像失败--没有采集影像!\n%s', traceback_info[2])
+
+ self.x = MessageBox('请先采集影像!')
+ self.x.exec()
+ else:
+ self.logger.critical('未知错误!\n%s', traceback_info[2])
+
+ def operate_success(self):
+ if self.qt_sender == 'image_mode_exposureTime_bt':
+ self.logger.info('自动曝光成功----------------!')
+ self.enable_bt_and_change_background_to_gray()
+
+ self.image_mode_exposureTime_bt.setText(re.sub('✔', '', self.image_mode_exposureTime_bt.text()) + '✔')
+ elif self.qt_sender == 'image_mode_focus_bt':
+ self.logger.info('调焦成功!')
+ self.enable_bt_and_change_background_to_gray()
+
+ self.image_mode_focus_bt.setText(re.sub('✔', '', self.image_mode_focus_bt.text()) + '✔')
+ elif self.qt_sender == 'image_mode_dc_bt':
+ self.logger.info('采集暗电流成功!')
+ self.enable_bt_and_change_background_to_gray()
+
+ self.image_mode_dc_bt.setText(re.sub('✔', '', self.image_mode_dc_bt.text()) + '✔')
+ elif self.qt_sender == 'image_mode_record_bt':
+ self.logger.info('采集影像成功!')
+
+ self.image_mode_record_bt.setText('采集')
+ self.image_mode_record_bt.setDisabled(True) # 要等马达回到初始位置才能用
+ self.record_count += 1
+
+ self.image_mode_record_bt.setText(re.sub('✔', '', self.image_mode_record_bt.text()) + '✔')
+
+ self.save_bt.setText(re.sub('✔', '', self.save_bt.text()))
+
+ worker = Worker(self.return_arcus_after_operate_success)
+ self.threadpool.start(worker)
+ elif self.qt_sender == 'save_bt':
+ self.save_bt.setText(re.sub('✔', '', self.save_bt.text()) + '✔')
+ self.enable_bt_and_change_background_to_gray()
+
+ self.image_mode_record_bt.setText(re.sub('✔', '', self.image_mode_record_bt.text()))
+
+ self.logger.info('保存影像成功!')
+
+ def return_arcus_after_operate_success(self):
+ while True:
+ python2_command = r'python2.exe ' + get_resource_path(
+ './data/ArcusDevice.py') + ' PX'
+ process = subprocess.Popen(python2_command.split(), stdout=subprocess.PIPE)
+
+ try:
+ output, error = process.communicate(timeout=2)
+ if 'arcus is return to initial position' in output.decode('utf-8'):
+ self.enable_bt_and_change_background_to_gray()
+
+ break
+ elif 'No arcus devices' in output.decode('utf-8') or 'Cannot connect Arcus device' in output.decode('utf-8'):
+ self.enable_bt_and_change_background_to_gray()
+
+ break
+ elif 'arcus is still returning' in output.decode('utf-8'):
+ pass
+ except subprocess.TimeoutExpired:
+ process.kill()
+ output2, error2 = process.communicate()
+ if 'Arcus device connected' in output2.decode('utf-8'):
+ self.enable_bt_and_change_background_to_gray()
+
+ break
+ elif 'No arcus devices' in output2.decode('utf-8') or 'Cannot connect Arcus device' in output2.decode('utf-8'):
+ self.enable_bt_and_change_background_to_gray()
+
+ break
+
+ def enable_bt_and_change_background_to_gray(self):
+ self.disable_bt(False)
+
+ # 当操作成功后,所有按钮都变为初始颜色:灰色
+ self.change_widget_background_color(self.image_mode_exposureTime_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_focus_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_dc_bt, 'gray')
+ self.change_widget_background_color(self.image_mode_record_bt, 'gray')
+ self.change_widget_background_color(self.save_bt, 'gray')
+
+ # 保存影像数据
+ def savedata(self):
+ self.disable_bt(True) # 因为保存影像所需时间较多,所以需要将此行代码放在最前面
+
+ # 保存路径
+ # filename = "%s%s%s" % (re.sub('/', '\\\\', self.config_file_object.image_dir), '\\', self.config_file_object.default_image_name)
+ filename, file_number = return_file_path([], self.config_file_object.image_dir,
+ self.config_file_object.default_image_name)
+
+ # 保存影像和头文件
+ imagefile = "%s%s%s" % (os.getcwd(), '\\', 'corning410_test')
+ shutil.copyfile(imagefile, filename)
+ shutil.copyfile("%s%s" % (imagefile, '.hdr'), "%s%s" % (filename, '.hdr'))
+
+ self.file_number_label.setText(str(file_number))
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和self.config对象中
+ def post_auto_expose(self, result):
+ '''
+ :param result: return cam.get_exposure(), cam.get_gain(), cls.autoexposure_feedback
+ :return:
+ '''
+ try:
+ # 将自动曝光得到的结果显示到界面(QLineEdit)
+ self.exposure_time_le.setText(str(result[0]))
+
+ # 为了防止后面的信号执行延迟;如果延迟,设置曝光时间就会设置为self.config.exposure_time的旧值
+ self.config_file_object.exposure_time = result[0]
+ self.config_file_object.gain = result[1]
+
+ try:
+ # 将自动曝光值保存到配置文件中
+ self.config_file_object.image_signal.emit({'exposure_time': result[0], 'gain': result[1]})
+ except:
+ traceback.print_exc()
+
+
+ self.image_camera_operation.set_exposure_gain_framerate(camera)
+
+ if result[2] == 1:
+ self.x = MessageBox('光线不足,曝光时间已设置为最大!')
+ self.x.exec()
+ self.image_camera_operation.autoexposure_feedback = 0
+ except:
+ traceback.print_exc()
+
+ def closeEvent(self, a0: QtGui.QCloseEvent):
+ camera.stop_acquisition()
+
+
+# 光谱窗口
+class SpectralWindow(QDialog, Ui_spectral_Window_phone):
+ # 信号必须定义为类属性,不能放在__init__方法里
+ auto_expose_signal = pyqtSignal(int)
+ progress_bar_signal = pyqtSignal(int)
+ plot_spectral_signal = pyqtSignal()
+ save_spectral_signal = pyqtSignal(int)
+ operate_success_signal = pyqtSignal()
+
+ def __init__(self, parent=None):
+ super(SpectralWindow, self).__init__(parent)
+ self.setupUi(self)
+ self.setWindowState(Qt.WindowMaximized) # 初始化时就最大化窗口
+ self.setWindowModality(Qt.ApplicationModal) # 阻塞此窗口:此行代码必须放在show()函数之前
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ # 配置文件读取和写入类,配置文件读写和界面分离
+ # 1、采集数据需要的帧率、曝光、帧数、文件名等等都由此类从文件中读取
+ # 2、并保存在此类中
+ self.config_file_object = ConfigFile()
+
+ # 暗电流/白板 计时
+ self.dc_time = time.time() # 用于暗电流计时(从采集成功后那一刻开始)
+ self.dc_timer = QTimer(self)
+ self.dc_timer.timeout.connect(self.dc_timer_slot)
+
+ self.wb_time = time.time() # 用于暗电流计时(从采集成功后那一刻开始)
+ self.wb_timer = QTimer(self)
+ self.wb_timer.timeout.connect(self.wb_timer_slot)
+
+ self.progressBar.setMaximum(self.config_file_object.framenumber_average)
+ self.progressBar.setValue(0)
+
+ # log
+ self.logger = logging.getLogger('root.spectral')
+ if not os.path.exists(self.config_file_object.log_dir + '//spectral_operate.log'):
+ with open(self.config_file_object.log_dir + '//spectral_operate.log', 'w') as f:
+ pass
+
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+ spectral_operate_file_handler = logging.FileHandler(self.config_file_object.log_dir + "//spectral_operate.log") # 输出到文件
+ spectral_operate_file_handler.setLevel(logging.INFO)
+ spectral_operate_file_handler.setFormatter(formatter)
+ self.logger.addHandler(spectral_operate_file_handler)
+
+ # 在窗口中显示串口接收的温度/湿度
+ serial_port.serial_signal.connect(self.update_temperature)
+ self.hpi_temperature = None # 暂时保存温度,当保存光谱文件时会用到
+
+ # 初始化值
+ self.filename_le.setText(self.config_file_object.default_spectral_name)
+ self.spectral_number_le.setText(str(self.config_file_object.spectral_number))
+ self.framenumber_average_le.setText(str(self.config_file_object.framenumber_average))
+ self.autoexposure_le.setText(str(self.config_file_object.exposure_time_spectral))
+
+ # 光谱显示控件
+ # self.spectralFigure = MatplotlibSpectralViewer(xlabel='Wavelength (nm)', ylabel='reflectance')
+ self.spectralFigure = QtSpectralViewer(ylabel_and_range='dn')
+ self.spe_glo.addWidget(self.spectralFigure)
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ self.filename_le.editingFinished.connect(self.onchange)
+ my_regex1 = QRegExp("[a-zA-Z0-9]*")
+ my_validator1 = QRegExpValidator(my_regex1, self.filename_le)
+ self.filename_le.setValidator(my_validator1)
+
+ self.autoexposure_le.editingFinished.connect(self.onchange)
+ my_regex2 = QRegExp("[0-9]*")
+ my_validator2 = QRegExpValidator(my_regex2, self.autoexposure_le)
+ self.autoexposure_le.setValidator(my_validator2)
+
+ self.spectral_number_le.editingFinished.connect(self.onchange)
+ self.framenumber_average_le.editingFinished.connect(self.onchange)
+ my_regex3 = QRegExp("[0-9]*")
+ my_validator3 = QRegExpValidator(my_regex2, self.autoexposure_le)
+ self.spectral_number_le.setValidator(my_validator2)
+ self.framenumber_average_le.setValidator(my_validator2)
+
+ # 数据采集保存类,采集数据并将数据保存在此类中,数据采集和界面分离
+ self.spectral_camera_operation = SpectralCameraOperation(self.hpi_temperature, self.config_file_object, self.progress_bar_signal,
+ self.plot_spectral_signal, self.save_spectral_signal,
+ self.auto_expose_signal, self.operate_success_signal)
+
+ # 当配置文件读取完成后,根据读取的配置文件设置相机曝光、帧率
+ self.spectral_camera_operation.set_exposure_gain_framerate(camera)
+
+ # 光谱仪状态
+ system_setting.camera_status_signal.connect(self.test_imager_status)
+
+ # 操作光谱仪
+ self.state = 0 # 光谱仪操作状态:曝光=1;暗电流=3;白板=5 → 所以只有state==9时才能开始采集光谱
+
+ self.auto_expose_signal.connect(self.auto_expose_signal_slot)
+ self.progress_bar_signal.connect(self.progress_bar_signal_slot)
+ self.plot_spectral_signal.connect(self.plot_spectral_signal_slot)
+ self.save_spectral_signal.connect(self.save_spectral2)
+ self.operate_success_signal.connect(self.operate_success)
+
+ self.spectral_mode_autoexposure_bt.clicked.connect(self.run)
+ self.spectral_mode_dc_bt.clicked.connect(self.run)
+ self.spectral_mode_wb_bt.clicked.connect(self.run)
+ self.spectral_mode_record_bt.clicked.connect(self.run)
+
+ self.core_operation()
+
+ def core_operation(self):
+ worker = Worker(self.spectral_camera_operation.start_AcquireData, camera)
+ self.threadpool.start(worker)
+
+ # 将自动曝光返回值写入到界面中的QLineEdit和self.config_file_object对象中
+ def auto_expose_signal_slot(self, x):
+ '''
+ 自动曝光完成后,会通过信号发送自动曝光获得的曝光时间,将此时间写入到界面中
+ :param x:
+ :return:
+ '''
+ self.autoexposure_le.setText(str(x))
+
+ self.config_file_object.spectral_signal.emit({'exposure_time_spectral': x})
+
+ def progress_bar_signal_slot(self, x):
+ self.progressBar.setValue(x)
+
+ def plot_spectral_signal_slot(self):
+ # 画出光谱
+ if self.data_type_comboBox.currentText() == 'DN':
+ self.spectralFigure.set_y_range(ylabel_and_range='dn')
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_dn_to_display[:, 0],
+ self.spectral_camera_operation.spectral_dn_to_display[:, 1])
+ if self.data_type_comboBox.currentText() == 'Rad':
+ self.spectralFigure.set_y_range(ylabel_and_range='radiance')
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_rad_to_display[:, 0],
+ self.spectral_camera_operation.spectral_rad_to_display[:, 1])
+ if self.data_type_comboBox.currentText() == 'Ref':
+ if self.spectral_camera_operation.spectral_wb is None:
+ self.data_type_comboBox.setCurrentIndex(0)
+ else:
+ self.spectralFigure.set_y_range(ylabel_and_range='reflectance')
+ self.spectralFigure.plot_wrap(self.spectral_camera_operation.spectral_ref_to_display[:, 0],
+ self.spectral_camera_operation.spectral_ref_to_display[:, 1])
+
+ def run(self):
+ self.qt_sender = self.sender().objectName()
+
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ print('SpectralWindow采集曝光')
+
+ self.logger.info('曝光...')
+
+ self.state = 1
+
+ self.spectral_camera_operation.auto_exposure_bool = True
+
+ self.change_widget_background_color(self.spectral_mode_autoexposure_bt, 'red')
+ self.disable_bt_le(True)
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ try:
+ if self.state == 0:
+ self.x = MessageBox('请先曝光!')
+ self.x.exec()
+ elif self.state == 1 or self.state == 4 or self.state == 9:
+ self.x = MessageBox('请先确认光纤盖已安装!')
+ self.x.exec()
+
+ self.logger.info('采集暗电流...')
+ self.state = 4
+
+ # 暗电流计时
+ self.dc_time = time.time()
+ self.dc_timer.start(2000)
+
+ self.spectral_camera_operation.image_dc_bool = True
+
+ self.change_widget_background_color(self.spectral_mode_dc_bt, 'red')
+ self.disable_bt_le(True)
+ except:
+ traceback.print_exc()
+ elif self.qt_sender == 'spectral_mode_wb_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光+暗电流!')
+ self.x.exec()
+ elif self.state == 1:
+ self.x = MessageBox('请先采集暗电流!')
+ self.x.exec()
+ elif self.state == 4 or self.state == 9:
+ self.logger.info('采集白板...')
+ self.state = 9
+
+ # 白板计时
+ self.wb_time = time.time()
+ self.wb_timer.start(2000)
+
+ self.spectral_camera_operation.spectral_wb_bool = True
+ self.data_type_comboBox.setCurrentIndex(1)
+
+ self.change_widget_background_color(self.spectral_mode_wb_bt, 'red')
+ self.disable_bt_le(True)
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ if self.state == 0:
+ self.x = MessageBox('请先曝光+暗电流+白板')
+ self.x.exec()
+ elif self.state == 1:
+ self.x = MessageBox('请先暗电流+白板')
+ self.x.exec()
+ elif self.state == 4:
+ self.x = MessageBox('请先白板')
+ self.x.exec()
+ elif self.state == 9:
+ self.logger.info('采集光谱...')
+
+ self.spectral_camera_operation.save_bool = True
+
+ self.change_widget_background_color(self.spectral_mode_record_bt, 'red')
+ self.disable_bt_le(True)
+
+ def save_spectral2(self, x):
+ print('保存光谱:', x)
+ # 保存光谱
+ filename_dn, file_number_dn = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_dn',
+ model='spectral')
+ filename_rad, file_number_rad = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_rad',
+ model='spectral')
+ filename_ref, file_number_ref = return_file_path([], self.config_file_object.spectral_dir,
+ self.config_file_object.default_spectral_name + '_ref',
+ model='spectral')
+ # print(filename_ref)
+
+ header_dn = self.get_spectral_metadata('DN')
+ header_rad = self.get_spectral_metadata('RAD')
+ header_ref = self.get_spectral_metadata('REF')
+
+ np.savetxt(filename_dn, self.spectral_camera_operation.spectral_dn[:, [0, x]], fmt='%f', header=header_dn)
+ np.savetxt(filename_rad, self.spectral_camera_operation.spectral_rad[:, [0, x]], fmt='%f', header=header_rad)
+ np.savetxt(filename_ref, self.spectral_camera_operation.spectral_ref[:, [0, x]], fmt='%f', header=header_ref)
+
+ self.file_number_label.setText(str(file_number_dn + 1))
+
+ def operate_success(self):
+ # 操作状态显示
+ if self.qt_sender == 'spectral_mode_autoexposure_bt':
+ self.logger.info('曝光成功!')
+ elif self.qt_sender == 'spectral_mode_dc_bt':
+ self.logger.info('采集暗电流成功!')
+ elif self.qt_sender == 'spectral_mode_wb_bt':
+ self.logger.info('采集白板成功!')
+ elif self.qt_sender == 'spectral_mode_align_bt':
+ self.logger.info('align successfully!')
+ elif self.qt_sender == 'spectral_mode_record_bt':
+ self.logger.info('采集光谱成功!')
+
+ self.disable_bt_le(False)
+
+ # 当操作成功后,所有按钮都变为初始颜色:灰色
+ self.change_widget_background_color(self.spectral_mode_autoexposure_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_dc_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_wb_bt, 'gray')
+ self.change_widget_background_color(self.spectral_mode_record_bt, 'gray')
+
+ def disable_bt_le(self, bool):
+ self.spectral_mode_autoexposure_bt.setDisabled(bool)
+ self.spectral_mode_dc_bt.setDisabled(bool)
+ self.spectral_mode_wb_bt.setDisabled(bool)
+ self.spectral_mode_record_bt.setDisabled(bool)
+
+ self.spectral_number_le.setDisabled(bool)
+ self.framenumber_average_le.setDisabled(bool)
+ self.autoexposure_le.setDisabled(bool)
+ self.filename_le.setDisabled(bool)
+
+ def closeEvent(self, a0: QtGui.QCloseEvent):
+ camera.stop_acquisition()
+
+ # 改变按钮三态中普通态的背景颜色
+ def change_widget_background_color(self, qt_widget, color):
+ pattern = re.compile('background-color(.*)(normal\*/)')
+ old_style_sheet = qt_widget.styleSheet()
+
+ if color == 'red':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(255 , 0 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'green':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(0 , 255 , 0);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+ elif color == 'gray':
+ new_style_sheet = re.sub(pattern, r'background-color:rgb(225 , 225 , 225);/*normal*/', old_style_sheet)
+ qt_widget.setStyleSheet(new_style_sheet)
+
+ def dc_timer_slot(self):
+ now = time.time()
+ x = now - self.dc_time
+ self.dc_timer_label.setText(str(int(x)) + 's')
+
+ def wb_timer_slot(self):
+ now = time.time()
+ x = now - self.wb_time
+ self.wb_timer_label.setText(str(int(x)) + 's')
+
+ def get_spectral_metadata(self, data_type_str):
+
+ record_time = "%s%s" % ('RecordTime = ', str(datetime.datetime.now()))
+ SN = 'SN = 0001'
+ exposure_time = "%s%s" % ('ExposureTime = ', str(camera.get_exposure()))
+ data_type = "%s%s" % ('DataType = ', data_type_str)
+ sensor_temperature = "%s%s" % ('sensor_temperature = ', str(camera.get_temp()))
+ hpi_temperature = "%s%s" % ('hpi_temperature = ', str(self.hpi_temperature))
+
+ header = '%s%s%s%s%s%s%s%s%s%s%s' % (
+ record_time, '\n', SN, '\n', exposure_time, '\n', data_type, '\n', sensor_temperature, '\n', hpi_temperature)
+ return header
+
+ def update_temperature(self, data):
+ try:
+ self.hpi_temperature = data[0]
+
+ self.t_label.setText('温度:' + data[0])
+ self.hum_label.setText('湿度:' + data[1])
+
+ self.change_widget_background_color(self.t_label, 'green')
+ self.change_widget_background_color(self.hum_label, 'green')
+ except:
+ traceback.print_exc()
+ print('有问题')
+ self.t_label.setVisible(False)
+ self.hum_label.setVisible(False)
+ self.t_label.setText('温度:无数据')
+ self.hum_label.setText('湿度:无数据')
+
+ # 手动改变窗口中的值,然后将值写入spectral_camera_operation类对应的变量中
+ def onchange(self):
+ try:
+ if self.sender().objectName() == 'autoexposure_le':
+ self.state = 1 # 手动改变曝光时间后,需要强制让用户重新采集暗电流和白板
+
+ exposure_time_tmp = int(float(self.autoexposure_le.text()))
+
+ self.config_file_object.spectral_signal.emit({'exposure_time_spectral': exposure_time_tmp})
+
+ camera.set_exposure(exposure_time_tmp) # 曝光时间单位为微秒,1s共有1000000微秒
+ # camera.set_gain(int(float(self.config_file_object.gain))) # int('0.0')会报错,int(float('0.0'))不会报错
+
+ self.logger.info('手动改变曝光时间!')
+ elif self.sender().objectName() == 'framenumber_average_le':
+ self.x = MessageBox('请重新打开光谱模式!')
+ self.x.exec()
+ framenumber_average_tmp = int(float(self.framenumber_average_le.text()))
+
+ self.config_file_object.spectral_signal.emit({'framenumber_average': framenumber_average_tmp})
+
+ self.progressBar.setMaximum(framenumber_average_tmp)
+ # self.progressBar.setValue(0)
+
+ self.spectral_camera_operation.create_image_container(framenumber_average_tmp)
+
+ self.logger.info('手动改变每条光谱的平均帧数!')
+ elif self.sender().objectName() == 'spectral_number_le':
+ spectral_number_tmp = int(float(self.spectral_number_le.text()))
+
+ self.config_file_object.spectral_signal.emit({'spectral_number': spectral_number_tmp})
+
+ self.spectral_camera_operation.create_spectral_container(spectral_number_tmp)
+
+ self.logger.info('手动改变保存的光谱数!')
+ elif self.sender().objectName() == 'filename_le':
+ filename = self.filename_le.text()
+
+ if filename != '':
+ self.config_file_object.spectral_signal.emit({'default_spectral_name': filename})
+
+ self.logger.info('改变光谱文件名!')
+ except:
+ traceback.print_exc()
+
+ def test_imager_status(self, imager_status):
+ if imager_status == 1000: # 相机打开成功
+ # print('相机打开成功!')
+
+ try:
+ temperature = camera.get_temp()
+ except Exception:
+ temperature = None
+
+ self.camera_status_label.setText('光谱仪:' + str(temperature))
+ self.change_widget_background_color(self.camera_status_label, 'green')
+ elif imager_status == 1001:
+ print('相机打开时出现不是ximea错误的未知错误!')
+ elif imager_status == 1:
+ # print('相机已经断开连接!请重新打开软件尝试连接相机!')
+
+ self.camera_status_label.setText('光谱仪:断开连接')
+ self.change_widget_background_color(self.camera_status_label, 'red')
+
+ self.setEnabled(False)
+ self.close()
+ elif imager_status == 12:
+ pass
+ elif imager_status == 41:
+ pass
+ elif imager_status == 56:
+ print('没有检测到光谱仪!')
+ elif imager_status == 103:
+ pass
+
+
+# 影像模式类:相关的函数和变量
+class CameraOperation(object):
+ def __init__(self, hpi_temperature, config_file_object):
+ self.hpi_temperature = hpi_temperature
+ self.config_file_object = config_file_object
+ self.record_time_for_plot = 0 # 用于边采集边在页面中刷新,用于确定该显示多少帧了;如何确定该显示多少帧:self.record_time_for_plot * 帧率
+
+ self.get_wavelength_object = GetWavelength(self.config_file_object, self.hpi_temperature)
+
+ # 转辐亮度
+ self.rad_or_not = False
+ if self.config_file_object.binning == 1:
+ # self.img_gain = get_resource_path('./data/lens_bin1_gain_SN0031')
+ self.img_gain = get_resource_path('./data/' + self.config_file_object.calibration_file_name_image)
+ self.cal_it = self.config_file_object.calibration_file_it_image
+ elif self.config_file_object.binning == 2:
+ # self.img_gain = get_resource_path('./data/lens_bin2_gain_SN0031')
+ self.img_gain = get_resource_path('./data/' + self.config_file_object.calibration_file_name_image)
+ self.cal_it = self.config_file_object.calibration_file_it_image
+ _, _, self.gainTmp = ImageReaderWriter.read_img(self.img_gain)
+
+ self.gainTmp = self.gainTmp.astype(np.float32)
+ self.target_it = None
+ self.gain_scale = None
+
+ #
+ self.arcus_reverse_while_record = False
+ self.record_rad_bool = True # True → 采集rad影像,False → 采集dn影像
+
+ # 开始采集数据
+ self.image_dc = None # 此变量用于存储采集到的暗电流影像
+ self.focus = True # 用于停止调焦
+ self.record = True # 用于停止采集
+ self.img_datatype = 2 # 在头文件中确定影像数据类型:Integer(np.int16) → A 16-bit signed integer ranging from -32,768 to +32,767.
+
+ self.autoexposure_feedback = 0 # 指示:自动曝光所得到的shutter值是否为最大;如果为最大→值设置为1
+
+ # 创建rgb数据,用于在界面中显示
+ self.create_rgb()
+
+ def create_rgb(self):
+ self.rgb = np.ones((3, int(self.config_file_object.frame_number), self.config_file_object.end_column - self.config_file_object.start_column))
+
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposure_gain_framerate(self, cam):
+ # settings,cam.set_param("exposure",10000)
+ cam.set_framerate(self.config_file_object.framerate)
+ cam.set_exposure(self.config_file_object.exposure_time) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_gain(self.config_file_object.gain) #int('0.0')会报错,int(float('0.0'))不会报错
+
+ def start_AcquireData(self, cam, qt_sender, plot_signal=None): # qt_sender是指qt窗口中事件的发生者
+ '''
+ :param cam: 实例化的相机句柄
+ :param qt_sender: 调用本方法时,点击的界面上的按钮名;
+ :param plot_signal:
+ :return:
+ '''
+ # 创建img = xiapi.Image()前需要设置一系列img参数,例如:格式、位深度、
+ # 如果格式设置为XI_RAW8,image_raw_numpy.dtype -> dtype('uint8'), uint8
+ # 如果格式设置为XI_RAW16,image_raw_numpy.dtype -> dtype('= 4090:
+ cam.set_exposure(int(0.9 * cam.get_exposure()))
+
+ cam.start_acquisition()
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ image_raw_numpy = img.get_image_data_numpy()
+
+ # 当关闭调焦后,再次打开调焦功能需要将cls.focus的值从False变为True
+ if not self.focus:
+ self.focus = True
+
+ cam.start_acquisition()
+
+ while self.focus:
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ self.image_container = image_raw_numpy[
+ self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+
+ if plot_signal is not None:
+ plot_signal.emit()
+
+ # 调焦完成之后,将相机的曝光和帧率设置为配置文件中的值
+ self.set_exposure_gain_framerate(cam)
+
+ if qt_sender == 'image_mode_exposureTime_bt':
+ print('start_AcquireData--自动曝光运行开始')
+
+ # 设置自动曝光的CCD--roi
+ cam.set_framerate(self.config_file_object.framerate)
+
+ # cam.set_aeag_roi_offset_x(self.config_file_object.start_column)
+ # cam.set_aeag_roi_offset_y(self.config_file_object.start_row)
+ # cam.set_aeag_roi_height(self.config_file_object.end_row - self.config_file_object.start_row)
+ # cam.set_aeag_roi_width(self.config_file_object.end_column - self.config_file_object.start_column)
+
+ # cam.set_exp_priority(1) # Exposure priority (0.8 - exposure 80%, gain 20%).XI_PRM_EXP_PRIORITY
+ # cam.set_ae_max_limit(24000) # Maximum time (us) used for exposure in AEAG procedureXI_PRM_AE_MAX_LIMIT
+ # cam.set_ag_max_limit(12)
+ # cam.set_aeag_level(50) # Average intensity of output signal AEAG should achieve(in %)XI_PRM_AEAG_LEVEL
+ # 还有两个不知怎么用的参数:XI_PRM_GAIN_SELECTOR or "gain_selector"和XI_PRM_SHUTTER_TYPE or "shutter_type"
+
+ # 使用相机自动曝光功能得到初始曝光值
+ cam.enable_aeag() # 开启自动曝光
+ cam.start_acquisition()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ cam.disable_aeag() # 关闭自动曝光
+
+ # 根据自动曝光所得初始曝光值,循环迭代获取不过曝的曝光值
+ image_raw_numpy = img.get_image_data_numpy()
+ while image_raw_numpy.max() >= 2730:
+ cam.set_exposure(int(0.9 * cam.get_exposure()))
+
+ cam.start_acquisition()
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ image_raw_numpy = img.get_image_data_numpy()
+
+ # 如果因为光线不足曝光值达到了最大,就将曝光反馈变量设置为1
+ if cam.get_exposure() > int(1 / self.config_file_object.framerate * 10**6):
+ cam.set_exposure(int(1 / self.config_file_object.framerate * 10**6))
+ self.autoexposure_feedback = 1
+ else:
+ cam.set_exposure(cam.get_exposure())
+
+ # 计算gain
+ self.target_it = cam.get_exposure()
+ self.gain_scale = self.cal_it / self.target_it
+ self.gain = self.gainTmp * self.gain_scale
+
+ print('start_AcquireData--自动曝光运行结束')
+
+ # 如果点击“暗电流”按钮,采集并保存暗电流影像到image_dc
+ if qt_sender == 'image_mode_dc_bt':
+ framenumber = 10
+ image_container = np.empty((
+ self.config_file_object.end_row - self.config_file_object.start_row, framenumber,
+ self.config_file_object.end_column - self.config_file_object.start_column))
+
+ cam.start_acquisition()
+ print('Starting data acquisition...')
+ for i in range(framenumber):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ image_container[:, i, :] = image_raw_numpy[
+ self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+
+ image_container = image_container.mean(axis=1)
+
+ self.image_dc = image_container
+
+ # 如果点击“采集”按钮,自动去除暗电流,并且转化成反射率
+ if qt_sender == 'image_mode_record_bt':
+ self.record_time_for_plot = 0 # 每次点击采集按钮都将此变量设置为1,用于正常边采集影像边在界面中显示影像
+
+ frameCount = 1 # 统计采集的帧数,用于停止采集使用
+
+ # 当停止采集后,再次开始采集需要将cls.record的值从False变为True
+ if not self.record:
+ self.record = True
+
+ # 启动马达,可能造成死循环
+ self.arcus_start()
+
+ # 开始采集数据 并且 将数据写入到硬盘中
+ cam.start_acquisition()
+ with open('corning410_test', 'wb') as f:
+
+ print('Starting data acquisition...')
+ startTime = datetime.datetime.now()
+
+ while self.record:
+ cam.get_image(img) # get data and pass them from camera to img
+ # image_raw_numpy.dtype -> dtype('修正
+ :return: 返回波长温度漂移修正后的波长
+ '''
+ # # 计算波长:Serial number = 008
+ # wavelength = np.empty(639 - 339)
+ # for i in range(339, 639):
+ # wavelength[i - 339] = i * 1.999564 - 279.893
+
+ # wavelength = np.array(wavelength_tmp)
+
+ wavelength_file_name = get_resource_path('./data/' + self.config_file_object.wavelength_file_name)
+ wavelength = np.loadtxt(wavelength_file_name)
+
+ # 处理波长温漂
+ if self.hpi_temperature is None or self.hpi_temperature < 36:
+ pass
+ elif 36 < self.hpi_temperature <= 43:
+ wavelength = wavelength + 2
+ elif 43 < self.hpi_temperature <= 51:
+ wavelength = wavelength + 4
+ elif 51 < self.hpi_temperature:
+ wavelength = wavelength + 6
+
+ # 波长bin
+ if self.config_file_object.binning != 1:
+ wavelength_bin = np.zeros(int(300 / self.config_file_object.binning))
+ k = np.arange(300)[0::self.config_file_object.binning]
+ for i in range(wavelength_bin.shape[0]):
+ for j in range(self.config_file_object.binning):
+ wavelength_bin[i] += wavelength[k[i] + j]
+ wavelength_bin[i] = wavelength_bin[i] / self.config_file_object.binning
+ else:
+ wavelength_bin = wavelength
+
+ if model == 'str':
+ # 清洗波段数据
+ wavelength_str = str(wavelength_bin).replace('[', '').replace(']', '').replace('\n', '')
+ wavelength_str = re.sub(' +', ' ', wavelength_str)
+ wavelength_str = re.sub(' +$', '', wavelength_str) # 去除末尾的空格
+ wavelength_str = re.sub(' ', ', ', wavelength_str)
+
+ return wavelength_str
+ elif model == 'array':
+ return wavelength_bin
+
+
+# 光谱模式类:相关的函数和变量
+class SpectralCameraOperation(object):
+ def __init__(self, hpi_temperature, config_file_object, progress_bar_signal, plot_signals, save_spectral_signal,
+ auto_expose_signal, operate_success_signal):
+ self.hpi_temperature = hpi_temperature
+ self.config_file_object = config_file_object
+ self.progress_bar_signal = progress_bar_signal
+ self.plot_signals = plot_signals
+ self.save_spectral_signal = save_spectral_signal
+ self.auto_expose_signal = auto_expose_signal
+ self.operate_success_signal = operate_success_signal
+
+ self.get_wavelength_object = GetWavelength(self.config_file_object, self.hpi_temperature)
+
+ # 建立进程池
+ self.threadpool = QThreadPool()
+
+ # 转辐亮度
+ self.img_gain = get_resource_path('./data/' + self.config_file_object.calibration_file_name_spectral)
+ self.cal_it = self.config_file_object.calibration_file_it_spectral
+
+ # self.img_gain = get_resource_path('./data/optical_fiber_bin1_gain_SN0031')
+ # self.cal_it = 42300
+
+ self.rad_or_not = False # 判断是否通过辐亮度转换成反射率
+ _, _, self.gainTmp = ImageReaderWriter.read_img(self.img_gain)
+ self.gainTmp = self.gainTmp.astype(np.float)
+ self.gain = self.gainTmp
+ self.target_it = None
+ self.gain_scale = None
+
+ # 光谱暂时保存容器
+ self.spectral_dn = None
+ self.spectral_rad = None
+ self.spectral_ref = None
+ self.spectral_dn_to_display = None
+ self.spectral_rad_to_display = None
+ self.spectral_ref_to_display = None
+
+ # 开始采集数据
+ self.create_image_container(self.config_file_object.framenumber_average)
+ self.create_spectral_container(self.config_file_object.spectral_number)
+ self.refine_wavelength_wrapper()
+
+ self.image_dc = None
+ self.spectral_wb = None
+ # self.image_dc = np.empty((self.config_file_object.end_row - self.config_file_object.start_row,
+ # self.config_file_object.end_column - self.config_file_object.start_column)).astype(
+ # np.float) # 此变量用于存储采集到的暗电流,一帧平均得到
+ # self.spectral_wb = np.empty((self.config_file_object.end_row - self.config_file_object.start_row,
+ # self.config_file_object.end_column - self.config_file_object.start_column)).astype(
+ # np.float) # 此变量用于存储采集到的白板,一帧平均得到
+
+ self.image_dc_bool = False
+ self.spectral_wb_bool = False
+ self.save_bool = False
+ self.auto_exposure_bool = False
+
+ def create_image_container(self, framenumber_average):
+ self.image_container = np.empty(
+ (self.config_file_object.end_row - self.config_file_object.start_row, framenumber_average,
+ self.config_file_object.end_column - self.config_file_object.start_column)).astype(np.float)
+
+ def create_spectral_container(self, spectral_number):
+ self.number_of_spectral_to_save = spectral_number
+ self.number_of_spectral_saving = 1
+
+ # 用于暂时存储需要保存的光谱
+ self.spectral_dn = np.empty((self.config_file_object.end_row - self.config_file_object.start_row, spectral_number + 1)).astype(
+ np.float) # 此ndarray用于存储采集到的目标物光谱,每一列为一个光谱
+ self.spectral_rad = np.empty((self.config_file_object.end_row - self.config_file_object.start_row, spectral_number + 1)).astype(
+ np.float) # 此ndarray用于存储采集到的目标物光谱,每一列为一个光谱
+ self.spectral_ref = np.empty((self.config_file_object.end_row - self.config_file_object.start_row, spectral_number + 1)).astype(
+ np.float) # 此ndarray用于存储采集到的目标物光谱,每一列为一个光谱
+
+ # 用于存储显示所用光谱
+ self.spectral_dn_to_display = np.empty(
+ (self.config_file_object.end_row - self.config_file_object.start_row, 2)).astype(
+ np.float)
+ self.spectral_rad_to_display = np.empty(
+ (self.config_file_object.end_row - self.config_file_object.start_row, 2)).astype(
+ np.float)
+ self.spectral_ref_to_display = np.empty(
+ (self.config_file_object.end_row - self.config_file_object.start_row, 2)).astype(
+ np.float)
+
+ # 写入波长信息
+ wavelength = self.get_wavelength_object.wave(model='array')
+
+ self.spectral_dn[:, 0] = wavelength
+ self.spectral_rad[:, 0] = wavelength
+ self.spectral_ref[:, 0] = wavelength
+ self.spectral_dn_to_display[:, 0] = wavelength
+ self.spectral_rad_to_display[:, 0] = wavelength
+ self.spectral_ref_to_display[:, 0] = wavelength
+
+ def refine_wavelength_wrapper(self):
+ worker = Worker(self.refine_wavelength)
+ self.threadpool.start(worker)
+
+ def refine_wavelength(self):
+ '''
+ 1:调用时机:当调用了方法(create_spectral_container),创建了光谱容器后
+ 2:本函数作用:调用self.wave()进行波长温度漂移校正
+ :return:
+ '''
+
+ while True:
+ wavelength = self.get_wavelength_object.wave(model='array')
+
+ if self.spectral_dn is not None:
+ self.spectral_dn[:, 0] = wavelength
+ self.spectral_rad[:, 0] = wavelength
+ self.spectral_ref[:, 0] = wavelength
+ self.spectral_dn_to_display[:, 0] = wavelength
+ self.spectral_rad_to_display[:, 0] = wavelength
+ self.spectral_ref_to_display[:, 0] = wavelength
+
+ time.sleep(2)
+
+ def start_AcquireData(self, cam):
+ cam.set_imgdataformat('XI_RAW16')
+ # create instance of Image to store image data and metadata
+ img = xiapi.Image()
+ cam.start_acquisition()
+ while True:
+ if self.auto_exposure_bool: # 自动曝光
+ # cam.set_aeag_roi_offset_x(self.config_file_object.start_column)
+ # cam.set_aeag_roi_offset_y(self.config_file_object.start_row)
+ # cam.set_aeag_roi_height(self.config_file_object.end_row - self.config_file_object.start_row)
+ # cam.set_aeag_roi_width(self.config_file_object.end_column - self.config_file_object.start_column)
+
+ cam.enable_aeag()
+ for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.disable_aeag()
+
+ self.auto_expose_signal.emit(cam.get_exposure())
+
+ # 计算gain
+ self.target_it = cam.get_exposure()
+ self.gain_scale = self.cal_it / self.target_it
+ self.gain = self.gainTmp * self.gain_scale # 这行代码有问题:每曝光一次,self.gain就变小一次
+
+ self.auto_exposure_bool = False # 执行一次自动曝光后,将此变量赋值False,以便下一次循环时,不执行自动曝光
+ self.operate_success_signal.emit()
+ else: # 正常采集光谱
+ # 采集帧流
+ for i in range(self.config_file_object.framenumber_average):
+ cam.get_image(img) # get data and pass them from camera to img
+ image_raw_numpy = img.get_image_data_numpy()
+ self.image_container[:, i, :] = image_raw_numpy[
+ self.config_file_object.start_row:self.config_file_object.end_row,
+ self.config_file_object.start_column:self.config_file_object.end_column]
+ self.progress_bar_signal.emit(i+1) # 发射进度条信号:指示采集到了第几帧
+
+ # 判断是否采集暗电流/白板
+ if self.image_dc_bool:
+ self.image_dc = self.image_container.mean(axis=1)
+
+ self.operate_success_signal.emit()
+ self.image_dc_bool = False # 采集完成后,赋值False,以便下一次采集暗电流
+
+ if self.spectral_wb_bool:
+ if self.image_dc is not None:
+ self.spectral_wb = self.image_container.mean(axis=1) - self.image_dc
+ else:
+ self.spectral_wb = self.image_container.mean(axis=1)
+
+ self.operate_success_signal.emit()
+ self.spectral_wb_bool = False # 采集完成后,赋值False,以便下一次采集白板
+
+ # 判断是否扣除暗电流
+ if self.image_dc is not None:
+ self.one_frame = self.image_container.mean(axis=1) - self.image_dc
+ else:
+ self.one_frame = self.image_container.mean(axis=1)
+
+ # 当不采集暗电流/白板时,才能采集和绘制光谱
+ if not self.image_dc_bool and not self.spectral_wb_bool:
+ if self.save_bool: # 绘制 + 保存光谱
+ # 采集dn光谱
+ self.spectral_dn[:, self.number_of_spectral_saving] = self.one_frame.mean(axis=1)
+ self.spectral_dn_to_display[:, 1] = self.one_frame.mean(axis=1) # 用于显示
+
+ # 采集rad光谱
+ self.spectral_rad[:, self.number_of_spectral_saving] = (self.one_frame * self.gain[:, 0, :]).mean(axis=1)
+ self.spectral_rad_to_display[:, 1] = (self.one_frame * self.gain[:, 0, :]).mean(axis=1) # 用于显示
+
+ # 采集ref光谱
+ if self.rad_or_not: # 判断是否通过辐亮度转换成反射率
+ self.spectral_ref[:, self.number_of_spectral_saving] = ((self.one_frame * self.gain[:, 0, :]) / (
+ self.spectral_wb * self.gain[:, 0, :])).mean(axis=1)
+ self.spectral_ref_to_display[:, 1] = ((self.one_frame * self.gain[:, 0, :]) / (
+ self.spectral_wb * self.gain[:, 0, :])).mean(axis=1) # 用于显示
+ else:
+ self.spectral_ref[:, self.number_of_spectral_saving] = (self.one_frame / self.spectral_wb).mean(axis=1)
+ self.spectral_ref_to_display[:, 1] = (self.one_frame / self.spectral_wb).mean(axis=1) # 用于显示
+
+ # 判断是否采集完成
+ if self.number_of_spectral_saving == self.number_of_spectral_to_save:
+ self.save_spectral_signal.emit(self.number_of_spectral_saving) # 保存最后一条光谱
+
+ self.number_of_spectral_saving = 1
+ self.save_bool = False
+ self.operate_success_signal.emit()
+ else:
+ self.save_spectral_signal.emit(self.number_of_spectral_saving) # 保存除最后一条的所有光谱
+ self.number_of_spectral_saving += 1
+ else: # 当仅仅绘制光谱,不保存光谱
+ self.spectral_dn_to_display[:, 1] = self.one_frame.mean(axis=1)
+ self.spectral_rad_to_display[:, 1] = (self.one_frame * self.gain[:, 0, :]).mean(axis=1)
+ if self.spectral_wb is not None: # 转反射率
+ self.spectral_ref_to_display[:, 1] = (self.one_frame / self.spectral_wb).mean(axis=1)
+
+ self.plot_signals.emit() # 发射画图信号
+
+ # 手动改变界面上的曝光值和gain值后,设置相机的曝光值和gain值所用
+ def set_exposure_gain_framerate(self, cam):
+ cam.set_exposure(self.config_file_object.exposure_time_spectral) # 曝光时间单位为微秒,1s共有1000000微秒
+ cam.set_framerate(10)
+ # cam.set_gain(config_file_object.gain) # int('0.0')会报错,int(float('0.0'))不会报错
+
+
+class SystemSetting(QObject):
+ # 相机状态信号:ximea定义的错误 + 自己定义的错误
+ # 自己定义的错误:1000→相机打开成功;1001→未知错误
+ camera_status_signal = pyqtSignal(int) # 信号必须定义为类属性,不能放在__init__方法里
+
+ def __init__(self):
+ super(SystemSetting, self).__init__()
+
+ # 建立进程池:https://www.learnpyqt.com/courses/concurrent-execution/multithreading-pyqt-applications-qthreadpool/
+ self.threadpool = QThreadPool()
+ print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
+
+ self.cam_is_open = False # 因为程序逻辑,只能放在最前面;self.cam_is_open默认值是False,所以只在打开成功的情况下设置为True
+ self.cam_status = None # 相机状态信号:ximea定义的错误 + 自己定义的错误
+ # 自己定义的错误:1000→相机打开成功;1001→未知错误
+
+ self.config_file_object = ConfigFile()
+ self.open_camera()
+
+ self.timer = QTimer(self)
+ self.timer.timeout.connect(self.test_imager_status)
+ # self.timer.start(3000)
+
+ self.test_imager_status_wraper()
+
+ def test_imager_status_wraper(self):
+ # 在新线程中执行相机采集操作,避免相机采集数据时界面卡死
+ worker = Worker(self.test_imager_status)
+
+ self.threadpool.start(worker)
+
+ def test_imager_status(self):
+ while True:
+ if self.cam_is_open is True: # 只有当相机打开成功 → 不停循环检测相机的状态
+ try:
+ # self.cam.set_imgdataformat('XI_RAW16') # 这行代码在光谱仪在采集数据时,会出现各种错误
+ self.cam.get_temp()
+ except xiapi.Xi_error:
+ exctype, value = sys.exc_info()[:2]
+
+ if value.status == 1: # 在ximea的API中代表"Invalid handle":相机断开连接
+ self.cam_status = 1
+ self.camera_status_signal.emit(self.cam_status)
+ # print('错误代码:', 1, ' → 相机断开连接')
+ elif value.status == 12: # 在ximea的API中代表"Not supported":当相机正在采集数据时,执行代码cam.set_imgdataformat('XI_RAW16')
+ # 这代表相机工作正常,不用做出任何反应
+ self.cam_status = 12
+ self.camera_status_signal.emit(self.cam_status)
+ # print('相机现在不支持此操作!')
+ elif value.status == 41: # 在ximea的API中代表"Acquisition already started":相机已经开始采集数据
+ self.cam_status = 41
+ self.camera_status_signal.emit(self.cam_status)
+ # print('相机已经开始采集数据!')
+ elif value.status == 56: # 在ximea的API中代表"No Devices Found":在执行cam.open_device()时,无相机打开
+ self.cam_status = 56
+ self.camera_status_signal.emit(self.cam_status)
+ print('错误代码:', 56, ' → 代表无相机')
+ elif value.status == 103: # 在ximea的API中代表"Wrong parameter type":在没有执行cam.open_device()的情况下,执行了cam.set_imgdataformat('XI_RAW16')会出现此错误
+ self.cam_status = 103
+ self.camera_status_signal.emit(self.cam_status)
+ except Exception:
+ print('未知错误!!!!!!!!!!!!!')
+ else:
+ self.cam_status = 1000
+ self.camera_status_signal.emit(self.cam_status)
+ # print('相机打开成功!')
+ finally:
+ pass
+ else: # 如果相机没有打开成功就发射这些信号
+ self.camera_status_signal.emit(self.cam_status)
+
+ time.sleep(1)
+
+ # 打开相机
+ def open_camera(self):
+ '''
+ 打开相机,将打开相机的状态保存到变量self.cam_status中,然后通过函数test_imager_status中的信号发射出去
+ :return:
+ '''
+ try:
+ # create instance for first connected camera
+ self.cam = xiapi.Camera()
+
+ # start communication to open specific device, use: cam.open_device_by_SN('41305651')
+ print('Opening first camera...')
+ self.cam.open_device()
+
+ # 打开相机后,显示相机信息
+ # print('SN: %s' % str(self.cam.get_device_sn(), encoding="utf-8"))
+ # print('Device name: %s' % str(self.cam.get_device_name(), encoding="utf-8"))
+ # print('Device name: %s' % str(self.cam.get_device_type(), encoding="utf-8"))
+ # print('Instance path: %s' % str(self.cam.get_device_inst_path(), encoding="utf-8")) # Returns device instance path in operating system.
+ # print('Location path: %s' % str(self.cam.get_device_loc_path(), encoding="utf-8"))
+ # print('Debug level: %s' % self.cam.get_debug_level())
+
+ # The number of threads per image processor
+ print('Default number of threads per image processor: %d' % self.cam.get_proc_num_threads())
+ self.cam.set_proc_num_threads(8)
+ print('Current number of threads per image processor: %d' % self.cam.get_proc_num_threads())
+
+ # 图像水平翻转
+ # print('Is horizontal flip enabled? %s' % str(self.cam.is_horizontal_flip()))
+
+ # This mode is supported by selected camera families: CB, MC, MT, MX
+ self.cam.set_acq_timing_mode('XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ mode_used = self.cam.get_acq_timing_mode()
+ if mode_used == 'XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT':
+ print('Mode is XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ else:
+ print('Mode is not XI_ACQ_TIMING_MODE_FRAME_RATE_LIMIT')
+ sys.exit()
+ self.set_binning()
+ except xiapi.Xi_error: # 如果打开相机失败1 → ,出现错误(ximea错误)--这些错误已经有代码处理
+ exctype, value = sys.exc_info()[:2]
+
+ if value.status == 56: # 在ximea的API中代表"No Devices Found":在执行cam.open_device()时,无相机打开
+ self.cam_status = 56
+ if value.status == 57: # 在ximea的API中代表"Resource (device) or function locked by mutex"
+ self.cam_status = 57
+ else:
+ print('没有处理的ximea错误??????????????????????????????????错误代码:', value.status)
+ except Exception: # 如果打开相机失败2 → 出现错误(除了ximea错误意外的错误)--这些错误没有代码处理
+ self.camera_status_signal.emit(1001) # 这行代码会在EnterWindow实例化之前执行,所以对EnterWindow没有效果
+ self.cam_status = 1001
+ # print('相机打开时出现不是ximea错误的未知错误???????????????????????????????????')
+ else: # 如果打开没有出错
+ self.cam_is_open = True # self.cam_is_open默认值是False,所以只在打开成功的情况下设置为True
+ self.cam_status = 1000
+ finally:
+ pass
+
+ # 设置binning;设置裁剪有效窗口以提高帧率
+ def set_binning(self):
+ self.cam.set_binning_selector('XI_BIN_SELECT_HOST_CPU') # 默认为XI_BIN_SELECT_SENSOR(会报错),不可用:XI_BIN_SELECT_DEVICE_FPGA
+ self.cam.set_binning_horizontal_mode('XI_BIN_MODE_SUM')
+ self.cam.set_binning_horizontal(self.config_file_object.binning)
+ self.cam.set_binning_vertical_mode('XI_BIN_MODE_SUM')
+ self.cam.set_binning_vertical(self.config_file_object.binning)
+
+ self.cam.set_width(self.config_file_object.effective_window_width)
+ self.cam.set_offsetX(self.config_file_object.effective_window_offsetx)
+
+ self.cam.set_height(self.config_file_object.effective_window_height)
+ self.cam.set_offsetY(self.config_file_object.effective_window_offsety)
+
+ # if self.config_file_object.binning == 1:
+ # # # Serial number = 008
+ # # self.cam.set_width(1392)
+ # # self.cam.set_offsetX(272)
+ # #
+ # # self.cam.set_height(302)
+ # # self.cam.set_offsetY(338)
+ #
+ # # # Serial number = 0073
+ # # self.cam.set_width(1392)
+ # # self.cam.set_offsetX(272)
+ # #
+ # # self.cam.set_height(302)
+ # # self.cam.set_offsetY(364)
+ #
+ # # # Serial number = 0095
+ # # self.cam.set_width(1392)
+ # # self.cam.set_offsetX(272)
+ # #
+ # # self.cam.set_height(302)
+ # # self.cam.set_offsetY(324)
+ #
+ #
+ #
+ # # # Serial number = 0031
+ # # self.cam.set_width(1392)
+ # # self.cam.set_offsetX(272)
+ # #
+ # # self.cam.set_height(302)
+ # # self.cam.set_offsetY(406)
+ #
+ # # # Serial number = 0099
+ # # self.cam.set_width(1392)
+ # # self.cam.set_offsetX(272)
+ # #
+ # # self.cam.set_height(302)
+ # # self.cam.set_offsetY(354)
+ # elif self.config_file_object.binning == 2:
+ # # # Serial number = 008
+ # # self.cam.set_width(696)
+ # # self.cam.set_offsetX(128)
+ # #
+ # # self.cam.set_height(151)
+ # # self.cam.set_offsetY(168)
+ #
+ # # # Serial number = 0073
+ # # self.cam.set_width(696)
+ # # self.cam.set_offsetX(128)
+ # #
+ # # self.cam.set_height(151)
+ # # self.cam.set_offsetY(182)
+ #
+ # # # Serial number = 0095
+ # # self.cam.set_width(696)
+ # # self.cam.set_offsetX(128)
+ # #
+ # # self.cam.set_height(151)
+ # # self.cam.set_offsetY(162)
+ #
+ # # # Serial number = 0031
+ # # self.cam.set_width(696)
+ # # self.cam.set_offsetX(128)
+ # #
+ # # self.cam.set_height(151)
+ # # self.cam.set_offsetY(202)
+ #
+ # # # Serial number = 0099
+ # # self.cam.set_width(696)
+ # # self.cam.set_offsetX(128)
+ # #
+ # # self.cam.set_height(151)
+ # # self.cam.set_offsetY(176)
+
+ # 返回打开的相机对象
+ def get_cam(self):
+ return self.cam
+
+ def close_camera(self, cam):
+ # stop communication
+ cam.close_device()
+# 相机参数设置
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ # 创建根日志:root
+ log = Log()
+
+ # 用于获取温度传感器的数据
+ serial_port = SerialPort()
+
+ # 相机句柄,全局变量:用于整个程序
+ system_setting = SystemSetting()
+ camera = system_setting.get_cam()
+
+ # 实例化主窗口
+ enter_window_instance = EnterWindow(camera)
+ enter_window_instance.show()
+
+ sys.exit(app.exec_())
diff --git a/record_system_v28/delete.py b/record_system_v28/delete.py
new file mode 100644
index 0000000..e12ca46
--- /dev/null
+++ b/record_system_v28/delete.py
@@ -0,0 +1,63 @@
+from ximea import xiapi
+import numpy as np
+
+cam = xiapi.Camera()
+cam.open_device()
+
+
+
+# self.cam.set_width(1392)
+# cam.set_offsetX(272)
+#
+# cam.set_height(302)
+# cam.set_offsetY(338)
+
+
+# Serial number = 0031
+cam.set_width(1392)
+cam.set_offsetX(272)
+
+cam.set_height(302)
+cam.set_offsetY(406)
+
+framerate=20
+
+cam.set_framerate(framerate)
+
+
+# cam.set_aeag_roi_offset_x(self.config_file_object.start_column)
+# cam.set_aeag_roi_offset_y(self.config_file_object.start_row)
+# cam.set_aeag_roi_height(self.config_file_object.end_row - self.config_file_object.start_row)
+# cam.set_aeag_roi_width(self.config_file_object.end_column - self.config_file_object.start_column)
+
+
+img = xiapi.Image()
+
+# 使用相机自动曝光功能得到初始曝光值
+cam.enable_aeag() # 开启自动曝光
+cam.start_acquisition()
+for i in range(10):
+ cam.get_image(img) # get data and pass them from camera to img
+cam.stop_acquisition()
+cam.disable_aeag() # 关闭自动曝光
+
+
+# 根据自动曝光所得初始曝光值,循环迭代获取不过曝的曝光值
+img.get_image_data_numpy()
+image_raw_numpy = img.get_image_data_numpy()
+while image_raw_numpy.max() >= 2730:
+ cam.set_exposure(int(0.9 * cam.get_exposure()))
+
+ cam.start_acquisition()
+ cam.get_image(img) # get data and pass them from camera to img
+ cam.stop_acquisition()
+ image_raw_numpy = img.get_image_data_numpy()
+
+# 如果因为光线不足曝光值达到了最大,就将曝光反馈变量设置为1
+if cam.get_exposure() > int(1 / framerate * 10**6):
+ cam.set_exposure(int(1 / framerate * 10**6))
+ autoexposure_feedback = 1
+else:
+ cam.set_exposure(cam.get_exposure())
+
+haha=cam.get_exposure()
diff --git a/record_system_v28/log/corning_config - 20220627.ini b/record_system_v28/log/corning_config - 20220627.ini
new file mode 100644
index 0000000..bfe8c28
--- /dev/null
+++ b/record_system_v28/log/corning_config - 20220627.ini
@@ -0,0 +1,48 @@
+[bin]
+binning = 1
+start_column_binning_1 = 12
+end_column_binning_1 = 1376
+start_row_binning_1 = 1
+end_row_binning_1 = 301
+start_column_binning_2 = 13
+end_column_binning_2 = 695
+start_row_binning_2 = 1
+end_row_binning_2 = 151
+
+[effective_window]
+width_binning_1 = 1392
+offsetx_binning_1 = 272
+height_binning_1 = 302
+offsety_binning_1 = 364
+width_binning_2 = 696
+offsetx_binning_2 = 128
+height_binning_2 = 151
+offsety_binning_2 = 182
+
+[calibration_file]
+cal_file_name_image_bining_1 = lens_bin1_gain_SN0073
+cal_file_name_image_bining_2 = lens_bin2_gain_SN0073
+cal_file_it_image_bining_1 = 6969
+cal_file_it_image_bining_2 = 1628
+cal_file_name_spectral_bining_1 = optical_fiber_bin1_gain_SN0073
+cal_file_it_spectrl_bining_1 = 42300
+
+[wavelength_file_name]
+file_name = wavelength0073.txt
+
+[image_record_param]
+image_dir = D:\py_program\corning410\record_system_v28/image
+default_image_name = testimage
+framerate = 50
+exposure_time = 9367.0
+gain = 0.0
+frame_number = 20
+arcus_speed = 1000
+
+[spectral_record_param]
+spectral_dir = D:\py_program\corning410\record_system_v28/spectral
+default_spectral_name = testspectral
+spectral_number = 10
+framenumber_average = 10
+exposure_time_spectral = 69997
+
diff --git a/record_system_v28/log/corning_config.ini b/record_system_v28/log/corning_config.ini
new file mode 100644
index 0000000..98cf93b
--- /dev/null
+++ b/record_system_v28/log/corning_config.ini
@@ -0,0 +1,48 @@
+[bin]
+binning = 1
+start_column_binning_1 = 12
+end_column_binning_1 = 1376
+start_row_binning_1 = 1
+end_row_binning_1 = 301
+start_column_binning_2 = 13
+end_column_binning_2 = 695
+start_row_binning_2 = 1
+end_row_binning_2 = 151
+
+[effective_window]
+width_binning_1 = 1392
+offsetx_binning_1 = 272
+height_binning_1 = 302
+offsety_binning_1 = 364
+width_binning_2 = 696
+offsetx_binning_2 = 128
+height_binning_2 = 151
+offsety_binning_2 = 182
+
+[calibration_file]
+cal_file_name_image_bining_1 = lens_bin1_gain_SN0073
+cal_file_name_image_bining_2 = lens_bin2_gain_SN0073
+cal_file_it_image_bining_1 = 6969
+cal_file_it_image_bining_2 = 1628
+cal_file_name_spectral_bining_1 = optical_fiber_bin1_gain_SN0073
+cal_file_it_spectrl_bining_1 = 42300
+
+[wavelength_file_name]
+file_name = wavelength0073.txt
+
+[image_record_param]
+image_dir = D:\py_program\corning410\record_system_v28/image
+default_image_name = 20220627
+framerate = 10
+exposure_time = 23232
+gain = 0.0
+frame_number = 50
+arcus_speed = 800
+
+[spectral_record_param]
+spectral_dir = D:\py_program\corning410\record_system_v28/spectral
+default_spectral_name = testspectral
+spectral_number = 10
+framenumber_average = 10
+exposure_time_spectral = 69997
+
diff --git a/record_system_v28/ui/__init__.py b/record_system_v28/ui/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/record_system_v28/ui/enter_window.py b/record_system_v28/ui/enter_window.py
new file mode 100644
index 0000000..c84d4c9
--- /dev/null
+++ b/record_system_v28/ui/enter_window.py
@@ -0,0 +1,150 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'enter_window.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_enter_Window(object):
+ def setupUi(self, enter_Window):
+ enter_Window.setObjectName("enter_Window")
+ enter_Window.setEnabled(True)
+ enter_Window.resize(651, 474)
+ self.centralwidget = QtWidgets.QWidget(enter_Window)
+ self.centralwidget.setObjectName("centralwidget")
+ self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
+ self.gridLayout.setObjectName("gridLayout")
+ self.camstatus_label = QtWidgets.QLabel(self.centralwidget)
+ self.camstatus_label.setEnabled(True)
+ self.camstatus_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/\n"
+" /*color:white;*/\n"
+" /*背景颜色*/\n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}")
+ self.camstatus_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camstatus_label.setObjectName("camstatus_label")
+ self.gridLayout.addWidget(self.camstatus_label, 2, 0, 1, 1)
+ self.spectral_mode_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.spectral_mode_bt.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_bt.setObjectName("spectral_mode_bt")
+ self.gridLayout.addWidget(self.spectral_mode_bt, 1, 0, 1, 1)
+ self.image_mode_phone_bt = QtWidgets.QPushButton(self.centralwidget)
+ self.image_mode_phone_bt.setEnabled(True)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_phone_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_phone_bt.setSizePolicy(sizePolicy)
+ self.image_mode_phone_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_phone_bt.setObjectName("image_mode_phone_bt")
+ self.gridLayout.addWidget(self.image_mode_phone_bt, 0, 0, 1, 1)
+ enter_Window.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(enter_Window)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 651, 23))
+ self.menubar.setObjectName("menubar")
+ enter_Window.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(enter_Window)
+ self.statusbar.setObjectName("statusbar")
+ enter_Window.setStatusBar(self.statusbar)
+ self.actionwew_e = QtWidgets.QAction(enter_Window)
+ self.actionwew_e.setObjectName("actionwew_e")
+
+ self.retranslateUi(enter_Window)
+ QtCore.QMetaObject.connectSlotsByName(enter_Window)
+
+ def retranslateUi(self, enter_Window):
+ _translate = QtCore.QCoreApplication.translate
+ enter_Window.setWindowTitle(_translate("enter_Window", "主窗口"))
+ self.camstatus_label.setText(_translate("enter_Window", "正在打开相机..."))
+ self.spectral_mode_bt.setText(_translate("enter_Window", "光谱模式"))
+ self.image_mode_phone_bt.setText(_translate("enter_Window", "影像模式"))
+ self.actionwew_e.setText(_translate("enter_Window", "wew e"))
diff --git a/record_system_v28/ui/enter_window.ui b/record_system_v28/ui/enter_window.ui
new file mode 100644
index 0000000..75e1469
--- /dev/null
+++ b/record_system_v28/ui/enter_window.ui
@@ -0,0 +1,178 @@
+
+
+ enter_Window
+
+
+ true
+
+
+
+ 0
+ 0
+ 651
+ 474
+
+
+
+ 主窗口
+
+
+
+ -
+
+
+ true
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
+ 正在打开相机...
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 光谱模式
+
+
+
+ -
+
+
+ true
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 影像模式
+
+
+
+
+
+
+
+
+
+ wew e
+
+
+
+
+
+
diff --git a/record_system_v28/ui/image_Window_phone - 副本 (2).ui b/record_system_v28/ui/image_Window_phone - 副本 (2).ui
new file mode 100644
index 0000000..ac44ed4
--- /dev/null
+++ b/record_system_v28/ui/image_Window_phone - 副本 (2).ui
@@ -0,0 +1,1358 @@
+
+
+ image_Window_phone
+
+
+ true
+
+
+
+ 0
+ 0
+ 531
+ 1174
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 调 焦
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 保 存
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 140
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 命 名
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 积分时间
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 160
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 马 达
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ <
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ >
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ rad
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 数
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 70
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 反转
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 233
+ 12
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 马达:连接失败!
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v28/ui/image_Window_phone.py b/record_system_v28/ui/image_Window_phone.py
new file mode 100644
index 0000000..96c440f
--- /dev/null
+++ b/record_system_v28/ui/image_Window_phone.py
@@ -0,0 +1,868 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'image_Window_phone.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_image_Window_phone(object):
+ def setupUi(self, image_Window_phone):
+ image_Window_phone.setObjectName("image_Window_phone")
+ image_Window_phone.setEnabled(True)
+ image_Window_phone.resize(562, 1174)
+ image_Window_phone.setMouseTracking(False)
+ image_Window_phone.setAutoFillBackground(False)
+ image_Window_phone.setSizeGripEnabled(False)
+ image_Window_phone.setModal(False)
+ self.gridLayout_6 = QtWidgets.QGridLayout(image_Window_phone)
+ self.gridLayout_6.setObjectName("gridLayout_6")
+ self.frame_3 = QtWidgets.QFrame(image_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_3.sizePolicy().hasHeightForWidth())
+ self.frame_3.setSizePolicy(sizePolicy)
+ self.frame_3.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.frame_3)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.frame_7 = QtWidgets.QFrame(self.frame_3)
+ self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_7.setObjectName("frame_7")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_7)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.verticalLayout = QtWidgets.QVBoxLayout()
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.image_mode_focus_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_focus_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_focus_bt.setSizePolicy(sizePolicy)
+ self.image_mode_focus_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_focus_bt.setFont(font)
+ self.image_mode_focus_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_focus_bt.setAutoDefault(False)
+ self.image_mode_focus_bt.setObjectName("image_mode_focus_bt")
+ self.verticalLayout.addWidget(self.image_mode_focus_bt)
+ self.image_mode_exposureTime_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_exposureTime_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_exposureTime_bt.setSizePolicy(sizePolicy)
+ self.image_mode_exposureTime_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_exposureTime_bt.setFont(font)
+ self.image_mode_exposureTime_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_exposureTime_bt.setAutoDefault(False)
+ self.image_mode_exposureTime_bt.setObjectName("image_mode_exposureTime_bt")
+ self.verticalLayout.addWidget(self.image_mode_exposureTime_bt)
+ self.image_mode_dc_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_dc_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_dc_bt.setSizePolicy(sizePolicy)
+ self.image_mode_dc_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_dc_bt.setFont(font)
+ self.image_mode_dc_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_dc_bt.setAutoDefault(False)
+ self.image_mode_dc_bt.setObjectName("image_mode_dc_bt")
+ self.verticalLayout.addWidget(self.image_mode_dc_bt)
+ self.image_mode_record_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.image_mode_record_bt.sizePolicy().hasHeightForWidth())
+ self.image_mode_record_bt.setSizePolicy(sizePolicy)
+ self.image_mode_record_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.image_mode_record_bt.setFont(font)
+ self.image_mode_record_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.image_mode_record_bt.setAutoDefault(False)
+ self.image_mode_record_bt.setObjectName("image_mode_record_bt")
+ self.verticalLayout.addWidget(self.image_mode_record_bt)
+ self.save_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.save_bt.sizePolicy().hasHeightForWidth())
+ self.save_bt.setSizePolicy(sizePolicy)
+ self.save_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.save_bt.setFont(font)
+ self.save_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.save_bt.setAutoDefault(False)
+ self.save_bt.setObjectName("save_bt")
+ self.verticalLayout.addWidget(self.save_bt)
+ self.gridLayout_4.addLayout(self.verticalLayout, 0, 0, 1, 1)
+ self.gridLayout_5.addWidget(self.frame_7, 0, 0, 1, 1)
+ self.frame_6 = QtWidgets.QFrame(self.frame_3)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_6)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setObjectName("gridLayout_3")
+ self.frame_10 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_10.sizePolicy().hasHeightForWidth())
+ self.frame_10.setSizePolicy(sizePolicy)
+ self.frame_10.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_10.setObjectName("frame_10")
+ self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_10)
+ self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_8.setSpacing(0)
+ self.gridLayout_8.setObjectName("gridLayout_8")
+ self.rad_dn_comboBox = QtWidgets.QComboBox(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.rad_dn_comboBox.sizePolicy().hasHeightForWidth())
+ self.rad_dn_comboBox.setSizePolicy(sizePolicy)
+ self.rad_dn_comboBox.setMinimumSize(QtCore.QSize(90, 0))
+ self.rad_dn_comboBox.setStyleSheet("/*按钮普通态*/\n"
+"QComboBox\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}")
+ self.rad_dn_comboBox.setObjectName("rad_dn_comboBox")
+ self.rad_dn_comboBox.addItem("")
+ self.rad_dn_comboBox.addItem("")
+ self.gridLayout_8.addWidget(self.rad_dn_comboBox, 0, 2, 1, 1)
+ self.framenumber_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framenumber_le.sizePolicy().hasHeightForWidth())
+ self.framenumber_le.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.framenumber_le.setFont(font)
+ self.framenumber_le.setObjectName("framenumber_le")
+ self.gridLayout_8.addWidget(self.framenumber_le, 0, 1, 1, 1)
+ self.arcus_direction_bt = QtWidgets.QPushButton(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_direction_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_direction_bt.setSizePolicy(sizePolicy)
+ self.arcus_direction_bt.setMinimumSize(QtCore.QSize(90, 0))
+ self.arcus_direction_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_direction_bt.setFont(font)
+ self.arcus_direction_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_direction_bt.setAutoDefault(False)
+ self.arcus_direction_bt.setObjectName("arcus_direction_bt")
+ self.gridLayout_8.addWidget(self.arcus_direction_bt, 0, 3, 1, 1)
+ self.label_2 = QtWidgets.QLabel(self.frame_10)
+ self.label_2.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_2.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout_8.addWidget(self.label_2, 0, 0, 1, 1)
+ self.gridLayout_3.addWidget(self.frame_10, 4, 0, 1, 1)
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.label_3 = QtWidgets.QLabel(self.frame_6)
+ self.label_3.setMinimumSize(QtCore.QSize(110, 0))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(20)
+ self.label_3.setFont(font)
+ self.label_3.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.horizontalLayout_3.addWidget(self.label_3)
+ self.framerate_le = QtWidgets.QLineEdit(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framerate_le.sizePolicy().hasHeightForWidth())
+ self.framerate_le.setSizePolicy(sizePolicy)
+ self.framerate_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.framerate_le.setFont(font)
+ self.framerate_le.setReadOnly(False)
+ self.framerate_le.setObjectName("framerate_le")
+ self.horizontalLayout_3.addWidget(self.framerate_le)
+ self.framenumber_recorded_label = QtWidgets.QLabel(self.frame_6)
+ self.framenumber_recorded_label.setMinimumSize(QtCore.QSize(180, 0))
+ self.framenumber_recorded_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.framenumber_recorded_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.framenumber_recorded_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.framenumber_recorded_label.setObjectName("framenumber_recorded_label")
+ self.horizontalLayout_3.addWidget(self.framenumber_recorded_label)
+ self.gridLayout_3.addLayout(self.horizontalLayout_3, 1, 0, 1, 1)
+ self.frame_9 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_9.sizePolicy().hasHeightForWidth())
+ self.frame_9.setSizePolicy(sizePolicy)
+ self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_9.setLineWidth(0)
+ self.frame_9.setObjectName("frame_9")
+ self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_9)
+ self.gridLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_7.setSpacing(0)
+ self.gridLayout_7.setObjectName("gridLayout_7")
+ self.filename_le = QtWidgets.QLineEdit(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.filename_le.sizePolicy().hasHeightForWidth())
+ self.filename_le.setSizePolicy(sizePolicy)
+ self.filename_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.filename_le.setFont(font)
+ self.filename_le.setObjectName("filename_le")
+ self.gridLayout_7.addWidget(self.filename_le, 0, 1, 1, 1)
+ self.label_6 = QtWidgets.QLabel(self.frame_9)
+ self.label_6.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_6.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_6.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_6.setObjectName("label_6")
+ self.gridLayout_7.addWidget(self.label_6, 0, 0, 1, 1)
+ self.file_number_label = QtWidgets.QLabel(self.frame_9)
+ self.file_number_label.setMinimumSize(QtCore.QSize(180, 0))
+ self.file_number_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.file_number_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.file_number_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.file_number_label.setObjectName("file_number_label")
+ self.gridLayout_7.addWidget(self.file_number_label, 0, 2, 1, 1)
+ self.gridLayout_3.addWidget(self.frame_9, 6, 0, 1, 1)
+ self.frame_5 = QtWidgets.QFrame(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth())
+ self.frame_5.setSizePolicy(sizePolicy)
+ self.frame_5.setMinimumSize(QtCore.QSize(160, 0))
+ self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_5.setObjectName("frame_5")
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_5)
+ self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ self.label_7 = QtWidgets.QLabel(self.frame_5)
+ self.label_7.setMinimumSize(QtCore.QSize(110, 0))
+ self.label_7.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_7.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_7.setObjectName("label_7")
+ self.horizontalLayout_2.addWidget(self.label_7)
+ self.arcus_left_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_left_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_left_bt.setSizePolicy(sizePolicy)
+ self.arcus_left_bt.setMinimumSize(QtCore.QSize(50, 0))
+ self.arcus_left_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_left_bt.setFont(font)
+ self.arcus_left_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_left_bt.setAutoDefault(False)
+ self.arcus_left_bt.setObjectName("arcus_left_bt")
+ self.horizontalLayout_2.addWidget(self.arcus_left_bt)
+ self.arcus_speed_le = QtWidgets.QLineEdit(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_speed_le.sizePolicy().hasHeightForWidth())
+ self.arcus_speed_le.setSizePolicy(sizePolicy)
+ self.arcus_speed_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.arcus_speed_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.arcus_speed_le.setFont(font)
+ self.arcus_speed_le.setObjectName("arcus_speed_le")
+ self.horizontalLayout_2.addWidget(self.arcus_speed_le)
+ self.arcus_right_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_right_bt.sizePolicy().hasHeightForWidth())
+ self.arcus_right_bt.setSizePolicy(sizePolicy)
+ self.arcus_right_bt.setMinimumSize(QtCore.QSize(50, 0))
+ self.arcus_right_bt.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.arcus_right_bt.setFont(font)
+ self.arcus_right_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.arcus_right_bt.setAutoDefault(False)
+ self.arcus_right_bt.setObjectName("arcus_right_bt")
+ self.horizontalLayout_2.addWidget(self.arcus_right_bt)
+ self.gridLayout_3.addWidget(self.frame_5, 3, 0, 1, 1)
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_4.setObjectName("horizontalLayout_4")
+ self.label_5 = QtWidgets.QLabel(self.frame_6)
+ self.label_5.setMinimumSize(QtCore.QSize(110, 0))
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(20)
+ self.label_5.setFont(font)
+ self.label_5.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:20pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_5.setObjectName("label_5")
+ self.horizontalLayout_4.addWidget(self.label_5)
+ self.exposure_time_le = QtWidgets.QLineEdit(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.exposure_time_le.sizePolicy().hasHeightForWidth())
+ self.exposure_time_le.setSizePolicy(sizePolicy)
+ self.exposure_time_le.setMaximumSize(QtCore.QSize(16777215, 106))
+ font = QtGui.QFont()
+ font.setPointSize(42)
+ self.exposure_time_le.setFont(font)
+ self.exposure_time_le.setObjectName("exposure_time_le")
+ self.horizontalLayout_4.addWidget(self.exposure_time_le)
+ self.gridLayout_3.addLayout(self.horizontalLayout_4, 2, 0, 1, 1)
+ self.gridLayout_5.addWidget(self.frame_6, 0, 1, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_3, 1, 0, 1, 1)
+ self.frame_4 = QtWidgets.QFrame(image_Window_phone)
+ self.frame_4.setMinimumSize(QtCore.QSize(0, 0))
+ self.frame_4.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_4.setObjectName("frame_4")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_4)
+ self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ spacerItem = QtWidgets.QSpacerItem(233, 12, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
+ self.t_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.t_label.sizePolicy().hasHeightForWidth())
+ self.t_label.setSizePolicy(sizePolicy)
+ self.t_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.t_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.t_label.setObjectName("t_label")
+ self.horizontalLayout.addWidget(self.t_label)
+ self.hum_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.hum_label.sizePolicy().hasHeightForWidth())
+ self.hum_label.setSizePolicy(sizePolicy)
+ self.hum_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.hum_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.horizontalLayout.addWidget(self.hum_label)
+ self.camera_status_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.camera_status_label.sizePolicy().hasHeightForWidth())
+ self.camera_status_label.setSizePolicy(sizePolicy)
+ self.camera_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.camera_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camera_status_label.setObjectName("camera_status_label")
+ self.horizontalLayout.addWidget(self.camera_status_label)
+ self.arcus_status_label = QtWidgets.QLabel(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.arcus_status_label.sizePolicy().hasHeightForWidth())
+ self.arcus_status_label.setSizePolicy(sizePolicy)
+ self.arcus_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.arcus_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.arcus_status_label.setObjectName("arcus_status_label")
+ self.horizontalLayout.addWidget(self.arcus_status_label)
+ self.gridLayout_6.addWidget(self.frame_4, 2, 0, 1, 1)
+ self.splitter = QtWidgets.QSplitter(image_Window_phone)
+ self.splitter.setOrientation(QtCore.Qt.Vertical)
+ self.splitter.setObjectName("splitter")
+ self.frame_2 = QtWidgets.QFrame(self.splitter)
+ self.frame_2.setFrameShape(QtWidgets.QFrame.Box)
+ self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_2.setObjectName("frame_2")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_2)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.image_glo = QtWidgets.QGridLayout()
+ self.image_glo.setObjectName("image_glo")
+ self.gridLayout_2.addLayout(self.image_glo, 0, 0, 1, 1)
+ self.frame = QtWidgets.QFrame(self.splitter)
+ self.frame.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame.setFrameShape(QtWidgets.QFrame.Box)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.gridLayout = QtWidgets.QGridLayout(self.frame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.focus_glo = QtWidgets.QGridLayout()
+ self.focus_glo.setObjectName("focus_glo")
+ self.gridLayout.addLayout(self.focus_glo, 0, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.splitter, 0, 0, 1, 1)
+
+ self.retranslateUi(image_Window_phone)
+ QtCore.QMetaObject.connectSlotsByName(image_Window_phone)
+
+ def retranslateUi(self, image_Window_phone):
+ _translate = QtCore.QCoreApplication.translate
+ image_Window_phone.setWindowTitle(_translate("image_Window_phone", "影像窗口"))
+ self.image_mode_focus_bt.setText(_translate("image_Window_phone", "调 焦"))
+ self.image_mode_exposureTime_bt.setText(_translate("image_Window_phone", "曝 光"))
+ self.image_mode_dc_bt.setText(_translate("image_Window_phone", "暗 电 流"))
+ self.image_mode_record_bt.setText(_translate("image_Window_phone", "采 集"))
+ self.save_bt.setText(_translate("image_Window_phone", "保 存"))
+ self.rad_dn_comboBox.setItemText(0, _translate("image_Window_phone", "rad"))
+ self.rad_dn_comboBox.setItemText(1, _translate("image_Window_phone", "dn"))
+ self.arcus_direction_bt.setText(_translate("image_Window_phone", "反转"))
+ self.label_2.setText(_translate("image_Window_phone", "帧 数"))
+ self.label_3.setText(_translate("image_Window_phone", "帧 率"))
+ self.framenumber_recorded_label.setText(_translate("image_Window_phone", "帧号"))
+ self.label_6.setText(_translate("image_Window_phone", "命 名"))
+ self.file_number_label.setText(_translate("image_Window_phone", "文件号"))
+ self.label_7.setText(_translate("image_Window_phone", "马 达"))
+ self.arcus_left_bt.setText(_translate("image_Window_phone", "<"))
+ self.arcus_right_bt.setText(_translate("image_Window_phone", ">"))
+ self.label_5.setText(_translate("image_Window_phone", "积分时间"))
+ self.t_label.setText(_translate("image_Window_phone", "温度:无数据"))
+ self.hum_label.setText(_translate("image_Window_phone", "湿度:无数据"))
+ self.camera_status_label.setText(_translate("image_Window_phone", "光谱仪:连接失败"))
+ self.arcus_status_label.setText(_translate("image_Window_phone", "马达:连接失败!"))
diff --git a/record_system_v28/ui/image_Window_phone.ui b/record_system_v28/ui/image_Window_phone.ui
new file mode 100644
index 0000000..3f0256b
--- /dev/null
+++ b/record_system_v28/ui/image_Window_phone.ui
@@ -0,0 +1,1395 @@
+
+
+ image_Window_phone
+
+
+ true
+
+
+
+ 0
+ 0
+ 562
+ 1174
+
+
+
+ false
+
+
+ 影像窗口
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 调 焦
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 保 存
+
+
+ false
+
+
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 90
+ 0
+
+
+
+ /*按钮普通态*/
+QComboBox
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
-
+
+ rad
+
+
+ -
+
+ dn
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 90
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 反转
+
+
+ false
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 数
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧 率
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+ false
+
+
+
+ -
+
+
+
+ 180
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 帧号
+
+
+ Qt::AlignCenter
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+ 0
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 命 名
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 180
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 160
+ 0
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 马 达
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ <
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ 42
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 50
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ >
+
+
+ false
+
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 110
+ 0
+
+
+
+
+ Microsoft Yahei
+ 20
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:20pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 积分时间
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 106
+
+
+
+
+ 42
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 233
+ 12
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 马达:连接失败!
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::Box
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+
+
+
+
+
diff --git a/record_system_v28/ui/spectral_Window_phone.py b/record_system_v28/ui/spectral_Window_phone.py
new file mode 100644
index 0000000..1843a1e
--- /dev/null
+++ b/record_system_v28/ui/spectral_Window_phone.py
@@ -0,0 +1,635 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'spectral_Window_phone.ui'
+#
+# Created by: PyQt5 UI code generator 5.13.0
+#
+# WARNING! All changes made in this file will be lost!
+
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+
+class Ui_spectral_Window_phone(object):
+ def setupUi(self, spectral_Window_phone):
+ spectral_Window_phone.setObjectName("spectral_Window_phone")
+ spectral_Window_phone.resize(728, 1175)
+ self.gridLayout_6 = QtWidgets.QGridLayout(spectral_Window_phone)
+ self.gridLayout_6.setObjectName("gridLayout_6")
+ self.frame = QtWidgets.QFrame(spectral_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
+ self.frame.setSizePolicy(sizePolicy)
+ self.frame.setMinimumSize(QtCore.QSize(0, 600))
+ self.frame.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame.setObjectName("frame")
+ self.gridLayout = QtWidgets.QGridLayout(self.frame)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.spe_glo = QtWidgets.QGridLayout()
+ self.spe_glo.setObjectName("spe_glo")
+ self.gridLayout.addLayout(self.spe_glo, 0, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame, 0, 0, 1, 1)
+ self.frame_2 = QtWidgets.QFrame(spectral_Window_phone)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
+ self.frame_2.setSizePolicy(sizePolicy)
+ self.frame_2.setMaximumSize(QtCore.QSize(16777215, 600))
+ self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_2.setObjectName("frame_2")
+ self.gridLayout_8 = QtWidgets.QGridLayout(self.frame_2)
+ self.gridLayout_8.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_8.setSpacing(0)
+ self.gridLayout_8.setObjectName("gridLayout_8")
+ self.frame_4 = QtWidgets.QFrame(self.frame_2)
+ self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_4.setObjectName("frame_4")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.frame_4)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setSpacing(0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.spectral_mode_autoexposure_bt = QtWidgets.QPushButton(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_autoexposure_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_autoexposure_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_autoexposure_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_autoexposure_bt.setAutoDefault(False)
+ self.spectral_mode_autoexposure_bt.setObjectName("spectral_mode_autoexposure_bt")
+ self.gridLayout_4.addWidget(self.spectral_mode_autoexposure_bt, 0, 0, 1, 1)
+ self.autoexposure_le = QtWidgets.QLineEdit(self.frame_4)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.autoexposure_le.sizePolicy().hasHeightForWidth())
+ self.autoexposure_le.setSizePolicy(sizePolicy)
+ self.autoexposure_le.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.autoexposure_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:40pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.autoexposure_le.setObjectName("autoexposure_le")
+ self.gridLayout_4.addWidget(self.autoexposure_le, 0, 1, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_4, 0, 0, 1, 1)
+ self.frame_6 = QtWidgets.QFrame(self.frame_2)
+ self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_6.setObjectName("frame_6")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.frame_6)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setSpacing(0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.dc_timer_label = QtWidgets.QLabel(self.frame_6)
+ self.dc_timer_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.dc_timer_label.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.dc_timer_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.dc_timer_label.setObjectName("dc_timer_label")
+ self.gridLayout_2.addWidget(self.dc_timer_label, 0, 1, 1, 1)
+ self.spectral_mode_dc_bt = QtWidgets.QPushButton(self.frame_6)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_dc_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_dc_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_dc_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_dc_bt.setAutoDefault(False)
+ self.spectral_mode_dc_bt.setObjectName("spectral_mode_dc_bt")
+ self.gridLayout_2.addWidget(self.spectral_mode_dc_bt, 0, 0, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_6, 1, 0, 1, 1)
+ self.frame_7 = QtWidgets.QFrame(self.frame_2)
+ self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_7.setObjectName("frame_7")
+ self.gridLayout_7 = QtWidgets.QGridLayout(self.frame_7)
+ self.gridLayout_7.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_7.setSpacing(0)
+ self.gridLayout_7.setObjectName("gridLayout_7")
+ self.spectral_mode_wb_bt = QtWidgets.QPushButton(self.frame_7)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_wb_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_wb_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_wb_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_wb_bt.setAutoDefault(False)
+ self.spectral_mode_wb_bt.setObjectName("spectral_mode_wb_bt")
+ self.gridLayout_7.addWidget(self.spectral_mode_wb_bt, 0, 0, 1, 1)
+ self.wb_timer_label = QtWidgets.QLabel(self.frame_7)
+ self.wb_timer_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.wb_timer_label.setStyleSheet("/*按钮普通态*/\n"
+"QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.wb_timer_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.wb_timer_label.setObjectName("wb_timer_label")
+ self.gridLayout_7.addWidget(self.wb_timer_label, 0, 1, 1, 1)
+ self.gridLayout_8.addWidget(self.frame_7, 2, 0, 1, 1)
+ self.frame_5 = QtWidgets.QFrame(self.frame_2)
+ self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_5.setObjectName("frame_5")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.frame_5)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setSpacing(0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.spectral_mode_record_bt = QtWidgets.QPushButton(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_mode_record_bt.sizePolicy().hasHeightForWidth())
+ self.spectral_mode_record_bt.setSizePolicy(sizePolicy)
+ self.spectral_mode_record_bt.setStyleSheet("/*按钮普通态*/\n"
+"QPushButton\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}\n"
+"\n"
+"/*按钮停留态*/\n"
+"QPushButton:hover\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(44 , 137 , 255);/*hover*/\n"
+" /*边框圆角半径为8像素*/\n"
+" /*border-radius:20px;*/\n"
+"}\n"
+"\n"
+"/*按钮按下态*/\n"
+"QPushButton:pressed\n"
+"{\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(255 , 0 , 0);/*pressed*/\n"
+"\n"
+" /*左内边距为3像素,让按下时字向右移动3像素*/ \n"
+" padding-left:3px;\n"
+"\n"
+" /*上内边距为3像素,让按下时字向下移动3像素*/ \n"
+" padding-top:3px;\n"
+"}")
+ self.spectral_mode_record_bt.setAutoDefault(False)
+ self.spectral_mode_record_bt.setObjectName("spectral_mode_record_bt")
+ self.gridLayout_5.addWidget(self.spectral_mode_record_bt, 0, 0, 1, 1)
+ self.data_type_comboBox = QtWidgets.QComboBox(self.frame_5)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.data_type_comboBox.sizePolicy().hasHeightForWidth())
+ self.data_type_comboBox.setSizePolicy(sizePolicy)
+ self.data_type_comboBox.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.data_type_comboBox.setStyleSheet("/*按钮普通态*/\n"
+"QComboBox\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" background-color:rgb(225 , 225 , 225);\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:20px;\n"
+"}")
+ self.data_type_comboBox.setFrame(False)
+ self.data_type_comboBox.setObjectName("data_type_comboBox")
+ self.data_type_comboBox.addItem("")
+ self.data_type_comboBox.addItem("")
+ self.data_type_comboBox.addItem("")
+ self.gridLayout_5.addWidget(self.data_type_comboBox, 0, 1, 1, 1)
+ self.progressBar = QtWidgets.QProgressBar(self.frame_5)
+ self.progressBar.setStyleSheet("QProgressBar\n"
+"{ \n"
+" background-color:rgb(225 , 225 , 225);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.progressBar.setProperty("value", 0)
+ self.progressBar.setTextVisible(False)
+ self.progressBar.setObjectName("progressBar")
+ self.gridLayout_5.addWidget(self.progressBar, 1, 0, 1, 2)
+ self.gridLayout_8.addWidget(self.frame_5, 3, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_2, 1, 0, 1, 1)
+ self.frame_3 = QtWidgets.QFrame(spectral_Window_phone)
+ self.frame_3.setMaximumSize(QtCore.QSize(16777215, 200))
+ self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_3.setObjectName("frame_3")
+ self.gridLayout_10 = QtWidgets.QGridLayout(self.frame_3)
+ self.gridLayout_10.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_10.setSpacing(0)
+ self.gridLayout_10.setObjectName("gridLayout_10")
+ self.frame_9 = QtWidgets.QFrame(self.frame_3)
+ self.frame_9.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_9.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_9.setObjectName("frame_9")
+ self.gridLayout_9 = QtWidgets.QGridLayout(self.frame_9)
+ self.gridLayout_9.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_9.setSpacing(0)
+ self.gridLayout_9.setObjectName("gridLayout_9")
+ self.filename_le = QtWidgets.QLineEdit(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.filename_le.sizePolicy().hasHeightForWidth())
+ self.filename_le.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(61)
+ self.filename_le.setFont(font)
+ self.filename_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:61pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.filename_le.setObjectName("filename_le")
+ self.gridLayout_9.addWidget(self.filename_le, 0, 2, 1, 1)
+ self.label_2 = QtWidgets.QLabel(self.frame_9)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
+ self.label_2.setSizePolicy(sizePolicy)
+ font = QtGui.QFont()
+ font.setFamily("Microsoft Yahei")
+ font.setPointSize(25)
+ self.label_2.setFont(font)
+ self.label_2.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout_9.addWidget(self.label_2, 0, 1, 1, 1)
+ self.file_number_label = QtWidgets.QLabel(self.frame_9)
+ self.file_number_label.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.file_number_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.file_number_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.file_number_label.setObjectName("file_number_label")
+ self.gridLayout_9.addWidget(self.file_number_label, 0, 3, 1, 1)
+ self.frame_10 = QtWidgets.QFrame(self.frame_9)
+ self.frame_10.setMinimumSize(QtCore.QSize(200, 0))
+ self.frame_10.setMaximumSize(QtCore.QSize(350, 16777215))
+ self.frame_10.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_10.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_10.setObjectName("frame_10")
+ self.gridLayout_11 = QtWidgets.QGridLayout(self.frame_10)
+ self.gridLayout_11.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_11.setSpacing(0)
+ self.gridLayout_11.setObjectName("gridLayout_11")
+ self.label_3 = QtWidgets.QLabel(self.frame_10)
+ self.label_3.setMinimumSize(QtCore.QSize(140, 0))
+ self.label_3.setMaximumSize(QtCore.QSize(110, 16777215))
+ self.label_3.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3.setObjectName("label_3")
+ self.gridLayout_11.addWidget(self.label_3, 0, 0, 1, 1)
+ self.label_4 = QtWidgets.QLabel(self.frame_10)
+ self.label_4.setMinimumSize(QtCore.QSize(140, 0))
+ self.label_4.setMaximumSize(QtCore.QSize(110, 16777215))
+ self.label_4.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:25pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.label_4.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_4.setObjectName("label_4")
+ self.gridLayout_11.addWidget(self.label_4, 1, 0, 1, 1)
+ self.spectral_number_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.spectral_number_le.sizePolicy().hasHeightForWidth())
+ self.spectral_number_le.setSizePolicy(sizePolicy)
+ self.spectral_number_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.spectral_number_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.spectral_number_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.spectral_number_le.setObjectName("spectral_number_le")
+ self.gridLayout_11.addWidget(self.spectral_number_le, 1, 2, 1, 1)
+ self.framenumber_average_le = QtWidgets.QLineEdit(self.frame_10)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.framenumber_average_le.sizePolicy().hasHeightForWidth())
+ self.framenumber_average_le.setSizePolicy(sizePolicy)
+ self.framenumber_average_le.setMinimumSize(QtCore.QSize(60, 0))
+ self.framenumber_average_le.setMaximumSize(QtCore.QSize(16777215, 16777215))
+ self.framenumber_average_le.setStyleSheet("QLineEdit\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" /*字体大小为20点*/\n"
+" font-size:30pt;\n"
+" /*字体颜色为白色*/ \n"
+" /*color:white;*/\n"
+" /*背景颜色*/ \n"
+" /*background-color:rgb(14 , 150 , 254);*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" /*border-radius:8px;*/\n"
+"}")
+ self.framenumber_average_le.setObjectName("framenumber_average_le")
+ self.gridLayout_11.addWidget(self.framenumber_average_le, 0, 2, 1, 1)
+ self.gridLayout_9.addWidget(self.frame_10, 0, 0, 1, 1)
+ self.gridLayout_10.addWidget(self.frame_9, 0, 0, 1, 1)
+ self.frame_8 = QtWidgets.QFrame(self.frame_3)
+ self.frame_8.setMaximumSize(QtCore.QSize(16777215, 35))
+ self.frame_8.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.frame_8.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.frame_8.setObjectName("frame_8")
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.frame_8)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setSpacing(0)
+ self.gridLayout_3.setObjectName("gridLayout_3")
+ spacerItem = QtWidgets.QSpacerItem(399, 15, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.gridLayout_3.addItem(spacerItem, 0, 0, 1, 1)
+ self.t_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.t_label.sizePolicy().hasHeightForWidth())
+ self.t_label.setSizePolicy(sizePolicy)
+ self.t_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.t_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.t_label.setObjectName("t_label")
+ self.gridLayout_3.addWidget(self.t_label, 0, 1, 1, 1)
+ self.hum_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.hum_label.sizePolicy().hasHeightForWidth())
+ self.hum_label.setSizePolicy(sizePolicy)
+ self.hum_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.hum_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.hum_label.setObjectName("hum_label")
+ self.gridLayout_3.addWidget(self.hum_label, 0, 2, 1, 1)
+ self.camera_status_label = QtWidgets.QLabel(self.frame_8)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.camera_status_label.sizePolicy().hasHeightForWidth())
+ self.camera_status_label.setSizePolicy(sizePolicy)
+ self.camera_status_label.setStyleSheet("QLabel\n"
+"{\n"
+" /*字体为微软雅黑*/\n"
+" font-family:Microsoft Yahei;\n"
+" background-color:rgb(255 , 0 , 0);/*normal*/\n"
+" /*边框圆角半径为8像素*/ \n"
+" border-radius:10px;\n"
+"}")
+ self.camera_status_label.setAlignment(QtCore.Qt.AlignCenter)
+ self.camera_status_label.setObjectName("camera_status_label")
+ self.gridLayout_3.addWidget(self.camera_status_label, 0, 3, 1, 1)
+ self.gridLayout_10.addWidget(self.frame_8, 1, 0, 1, 1)
+ self.gridLayout_6.addWidget(self.frame_3, 2, 0, 1, 1)
+
+ self.retranslateUi(spectral_Window_phone)
+ QtCore.QMetaObject.connectSlotsByName(spectral_Window_phone)
+
+ def retranslateUi(self, spectral_Window_phone):
+ _translate = QtCore.QCoreApplication.translate
+ spectral_Window_phone.setWindowTitle(_translate("spectral_Window_phone", "光谱窗口"))
+ self.spectral_mode_autoexposure_bt.setText(_translate("spectral_Window_phone", "曝 光"))
+ self.dc_timer_label.setText(_translate("spectral_Window_phone", "计时"))
+ self.spectral_mode_dc_bt.setText(_translate("spectral_Window_phone", "暗 电 流"))
+ self.spectral_mode_wb_bt.setText(_translate("spectral_Window_phone", "白 板"))
+ self.wb_timer_label.setText(_translate("spectral_Window_phone", "计时"))
+ self.spectral_mode_record_bt.setText(_translate("spectral_Window_phone", "采 集"))
+ self.data_type_comboBox.setCurrentText(_translate("spectral_Window_phone", "DN"))
+ self.data_type_comboBox.setItemText(0, _translate("spectral_Window_phone", "DN"))
+ self.data_type_comboBox.setItemText(1, _translate("spectral_Window_phone", "Ref"))
+ self.data_type_comboBox.setItemText(2, _translate("spectral_Window_phone", "Rad"))
+ self.label_2.setText(_translate("spectral_Window_phone", "文 件"))
+ self.file_number_label.setText(_translate("spectral_Window_phone", "文件号"))
+ self.label_3.setText(_translate("spectral_Window_phone", "自动平均"))
+ self.label_4.setText(_translate("spectral_Window_phone", "连续测量"))
+ self.t_label.setText(_translate("spectral_Window_phone", "温度:无数据"))
+ self.hum_label.setText(_translate("spectral_Window_phone", "湿度:无数据"))
+ self.camera_status_label.setText(_translate("spectral_Window_phone", "光谱仪:连接失败"))
diff --git a/record_system_v28/ui/spectral_Window_phone.ui b/record_system_v28/ui/spectral_Window_phone.ui
new file mode 100644
index 0000000..ec2c6bb
--- /dev/null
+++ b/record_system_v28/ui/spectral_Window_phone.ui
@@ -0,0 +1,1071 @@
+
+
+ spectral_Window_phone
+
+
+
+ 0
+ 0
+ 568
+ 1175
+
+
+
+ 光谱窗口
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 600
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 16777215
+ 600
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 曝 光
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:40pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 计时
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 暗 电 流
+
+
+ false
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 白 板
+
+
+ false
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 计时
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ /*按钮普通态*/
+QPushButton
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+/*按钮停留态*/
+QPushButton:hover
+{
+ /*背景颜色*/
+ background-color:rgb(44 , 137 , 255);/*hover*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:20px;*/
+}
+
+/*按钮按下态*/
+QPushButton:pressed
+{
+ /*背景颜色*/
+ background-color:rgb(255 , 0 , 0);/*pressed*/
+
+ /*左内边距为3像素,让按下时字向右移动3像素*/
+ padding-left:3px;
+
+ /*上内边距为3像素,让按下时字向下移动3像素*/
+ padding-top:3px;
+}
+
+
+ 采 集
+
+
+ false
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 200
+ 16777215
+
+
+
+ /*按钮普通态*/
+QComboBox
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ background-color:rgb(225 , 225 , 225);
+ /*边框圆角半径为8像素*/
+ border-radius:20px;
+}
+
+
+ DN
+
+
+ false
+
+
-
+
+ DN
+
+
+ -
+
+ Ref
+
+
+ -
+
+ Rad
+
+
+
+
+ -
+
+
+ QProgressBar
+{
+ background-color:rgb(225 , 225 , 225);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 0
+
+
+ false
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 200
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+
+ Microsoft Yahei
+ 61
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:61pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ Microsoft Yahei
+ 25
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文 件
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 200
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 文件号
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 200
+ 0
+
+
+
+
+ 350
+ 16777215
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+ 140
+ 0
+
+
+
+
+ 110
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 自动平均
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 140
+ 0
+
+
+
+
+ 110
+ 16777215
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:25pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ 连续测量
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 60
+ 0
+
+
+
+
+ 16777215
+ 16777215
+
+
+
+ QLineEdit
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ /*字体大小为20点*/
+ font-size:30pt;
+ /*字体颜色为白色*/
+ /*color:white;*/
+ /*背景颜色*/
+ /*background-color:rgb(14 , 150 , 254);*/
+ /*边框圆角半径为8像素*/
+ /*border-radius:8px;*/
+}
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 16777215
+ 35
+
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 399
+ 15
+
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 温度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 湿度:无数据
+
+
+ Qt::AlignCenter
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLabel
+{
+ /*字体为微软雅黑*/
+ font-family:Microsoft Yahei;
+ background-color:rgb(255 , 0 , 0);/*normal*/
+ /*边框圆角半径为8像素*/
+ border-radius:10px;
+}
+
+
+ 光谱仪:连接失败
+
+
+ Qt::AlignCenter
+
+
+
+
+
+
+
+
+
+
+
+
+
+