Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
beat
beat.editor
Commits
3666ccad
Commit
3666ccad
authored
Apr 17, 2019
by
Flavio TARSETTI
Committed by
Samuel GAIST
Oct 04, 2019
Browse files
[widgets] WIP: adding parameter.py
parent
adbe43f0
Changes
1
Hide whitespace changes
Inline
Side-by-side
beat/editor/widgets/parameter.py
0 → 100644
View file @
3666ccad
# vim: set fileencoding=utf-8 :
###############################################################################
# #
# Copyright (c) 2019 Idiap Research Institute, http://www.idiap.ch/ #
# Contact: beat.support@idiap.ch #
# #
# This file is part of the beat.editor module of the BEAT platform. #
# #
# Commercial License Usage #
# Licensees holding valid commercial BEAT licenses may use this file in #
# accordance with the terms contained in a written agreement between you #
# and Idiap. For further information contact tto@idiap.ch #
# #
# Alternatively, this file may be used under the terms of the GNU Affero #
# Public License version 3 as published by the Free Software and appearing #
# in the file LICENSE.AGPL included in the packaging of this file. #
# The BEAT platform is distributed in the hope that it will be useful, but #
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY #
# or FITNESS FOR A PARTICULAR PURPOSE. #
# #
# You should have received a copy of the GNU Affero Public License along #
# with the BEAT platform. If not, see http://www.gnu.org/licenses/. #
# #
###############################################################################
from
PyQt5.QtCore
import
pyqtSignal
from
PyQt5.QtWidgets
import
QPushButton
from
PyQt5.QtWidgets
import
QHBoxLayout
from
PyQt5.QtWidgets
import
QVBoxLayout
from
PyQt5.QtWidgets
import
QListWidget
# from PyQt5.QtWidgets import QTableView
# from PyQt5.QtWidgets import QTableWidget
# from PyQt5.QtWidgets import QTableWidgetItem
# from PyQt5.QtWidgets import QHeaderView
from
PyQt5.QtWidgets
import
QWidget
from
PyQt5.QtWidgets
import
QLabel
from
PyQt5.QtWidgets
import
QLineEdit
from
PyQt5.QtWidgets
import
QComboBox
from
PyQt5.QtWidgets
import
QStackedWidget
from
PyQt5.QtWidgets
import
QFormLayout
from
PyQt5.QtWidgets
import
QGroupBox
from
PyQt5.QtWidgets
import
QRadioButton
# from PyQt5.QtWidgets import QCheckBox
from
PyQt5.QtWidgets
import
QDoubleSpinBox
from
PyQt5.QtWidgets
import
QInputDialog
from
PyQt5.QtWidgets
import
QDialog
from
PyQt5.QtCore
import
Qt
# from PyQt5.QtGui import QDoubleValidator
from
.spinboxes
import
Int64SpinBox
from
.spinboxes
import
Uint64SpinBox
from
.spinboxes
import
Float64SpinBox
# from PyQt5.QtCore import QDateTime
# from PyQt5.QtWidgets import QDateTimeEdit
from
PyQt5.QtWidgets
import
QDialogButtonBox
import
pkg_resources
import
json
import
sys
import
numpy
from
enum
import
Enum
,
unique
# from beat.backend.python.algorithm import Storage
# from beat.backend.python.algorithm import Runner # noqa
# from beat.backend.python.algorithm import Algorithm as BackendAlgorithm
# from beat.core.schema import load_schema
NUMPY_TYPES
=
{
"int8"
:
numpy
.
iinfo
(
numpy
.
int8
),
"int16"
:
numpy
.
iinfo
(
numpy
.
int16
),
"int32"
:
numpy
.
iinfo
(
numpy
.
int32
),
"int64"
:
numpy
.
iinfo
(
numpy
.
int64
),
"uint8"
:
numpy
.
iinfo
(
numpy
.
uint8
),
"uint16"
:
numpy
.
iinfo
(
numpy
.
uint16
),
"uint32"
:
numpy
.
iinfo
(
numpy
.
uint32
),
"uint64"
:
numpy
.
iinfo
(
numpy
.
uint64
),
"float32"
:
numpy
.
finfo
(
numpy
.
float32
),
"float64"
:
numpy
.
finfo
(
numpy
.
float64
),
}
@
unique
class
InputType
(
Enum
):
"""All possible assets available on the BEAT platform"""
(
UNKNOWN
,
INT8
,
INT16
,
INT32
,
INT64
,
UINT8
,
UINT16
,
UINT32
,
UINT64
,
FLOAT32
,
FLOAT64
,
BOOL
,
STRING
,
)
=
range
(
13
)
@
classmethod
def
get_type
(
cls
,
type_
):
wanted_type
=
"unknown"
if
type_
==
cls
.
INT8
:
wanted_type
=
"int8"
elif
type_
==
cls
.
INT16
:
wanted_type
=
"int16"
elif
type_
==
cls
.
INT32
:
wanted_type
=
"int32"
elif
type_
==
cls
.
INT64
:
wanted_type
=
"int64"
if
type_
==
cls
.
UINT8
:
wanted_type
=
"uint8"
elif
type_
==
cls
.
UINT16
:
wanted_type
=
"uint16"
elif
type_
==
cls
.
UINT32
:
wanted_type
=
"uint32"
elif
type_
==
cls
.
UINT64
:
wanted_type
=
"uint64"
elif
type_
==
cls
.
FLOAT32
:
wanted_type
=
"float32"
elif
type_
==
cls
.
FLOAT64
:
wanted_type
=
"float64"
elif
type_
==
cls
.
BOOL
:
wanted_type
=
"bool"
elif
type_
==
cls
.
STRING
:
wanted_type
=
"string"
return
wanted_type
@
classmethod
def
from_type
(
cls
,
type_
):
if
type_
==
"int8"
:
return
cls
.
INT8
elif
type_
==
"int16"
:
return
cls
.
INT16
elif
type_
==
"int32"
:
return
cls
.
INT32
elif
type_
==
"int64"
:
return
cls
.
INT64
elif
type_
==
"uint8"
:
return
cls
.
UINT8
elif
type_
==
"uint16"
:
return
cls
.
UINT16
elif
type_
==
"uint32"
:
return
cls
.
UINT32
elif
type_
==
"uint64"
:
return
cls
.
UINT64
elif
type_
==
"float32"
:
return
cls
.
FLOAT32
elif
type_
==
"float64"
:
return
cls
.
FLOAT64
elif
type_
==
"bool"
:
return
cls
.
BOOL
elif
type_
==
"string"
:
return
cls
.
STRING
else
:
raise
RuntimeError
(
"Unknown asset type_ {}"
.
format
(
type_
))
# def validate(self, data):
# if self == self.UNKNOWN:
# raise RuntimeError("Trying to validate unknown type")
# return validate(self.name.lower(), data)
class
Type64Dialog
(
QDialog
):
def
__init__
(
self
,
selected_type
,
parent
=
None
):
super
(
Type64Dialog
,
self
).
__init__
(
parent
)
self
.
setWindowTitle
(
self
.
tr
(
"Input"
))
print
(
"type is here!: {}"
.
format
(
selected_type
))
layout
=
QVBoxLayout
(
self
)
self
.
label
=
QLabel
(
self
.
tr
(
"New Choice:"
))
if
InputType
.
from_type
(
selected_type
)
==
InputType
.
INT64
:
self
.
spinbox
=
Int64SpinBox
(
self
)
elif
InputType
.
from_type
(
selected_type
)
==
InputType
.
UINT64
:
self
.
spinbox
=
Uint64SpinBox
(
self
)
elif
InputType
.
from_type
(
selected_type
)
==
InputType
.
FLOAT64
:
self
.
spinbox
=
Float64SpinBox
(
self
)
layout
.
addWidget
(
self
.
label
)
layout
.
addWidget
(
self
.
spinbox
)
# OK and Cancel buttons
self
.
buttons
=
QDialogButtonBox
(
QDialogButtonBox
.
Ok
|
QDialogButtonBox
.
Cancel
,
Qt
.
Horizontal
,
self
)
layout
.
addWidget
(
self
.
buttons
)
self
.
buttons
.
accepted
.
connect
(
self
.
accept
)
self
.
buttons
.
rejected
.
connect
(
self
.
reject
)
# static method to create the dialog and return qdialog accepted/spinbox value
@
staticmethod
def
getDialog
(
selected_type
,
parent
=
None
):
dialog
=
Type64Dialog
(
selected_type
,
parent
)
result
=
dialog
.
exec_
()
return
(
dialog
.
spinbox
.
value
(),
result
==
QDialog
.
Accepted
)
class
ChoicesWidget
(
QWidget
):
def
__init__
(
self
,
parent
=
None
):
super
(
ChoicesWidget
,
self
).
__init__
(
parent
)
# Widgets
label
=
QLabel
(
self
.
tr
(
"Restrict to ..."
))
restricts
=
QComboBox
()
restricts
.
addItems
([
self
.
tr
(
"None"
),
self
.
tr
(
"Choices"
)])
# Layouts
layout
=
QHBoxLayout
()
layout
.
addWidget
(
label
)
layout
.
addWidget
(
restricts
)
self
.
setLayout
(
layout
)
def
get_information
(
self
):
return
"ChoicesWidget"
class
ChoicesRangeWidget
(
QWidget
):
def
__init__
(
self
,
parent
=
None
):
super
(
ChoicesRangeWidget
,
self
).
__init__
(
parent
)
print
(
self
.
get_information
())
print
(
dir
(
parent
))
print
(
parent
)
print
(
parent
.
selected_type
)
# Widgets
self
.
parent
=
parent
self
.
restrict_label
=
QLabel
(
self
.
tr
(
"Restrict to ..."
))
self
.
restricts
=
QComboBox
()
self
.
restricts
.
addItems
([
self
.
tr
(
"None"
),
self
.
tr
(
"Choices"
),
self
.
tr
(
"Range"
)])
self
.
default_label
=
QLabel
(
self
.
tr
(
"Default:"
))
self
.
default
=
QLineEdit
()
self
.
stacked_restricts
=
QStackedWidget
()
self
.
none_stack
=
QWidget
()
self
.
choices_stack
=
QWidget
()
self
.
range_stack
=
QWidget
()
self
.
none_stack_ui
()
self
.
choices_stack_ui
()
self
.
range_stack_ui
()
self
.
Stack
=
QStackedWidget
(
self
)
self
.
Stack
.
addWidget
(
self
.
none_stack
)
self
.
Stack
.
addWidget
(
self
.
choices_stack
)
self
.
Stack
.
addWidget
(
self
.
range_stack
)
# Layouts
layout
=
QHBoxLayout
()
layout
.
addWidget
(
self
.
restrict_label
)
layout
.
addWidget
(
self
.
restricts
)
layout
.
addWidget
(
self
.
default_label
)
layout
.
addWidget
(
self
.
default
)
layout
.
addWidget
(
self
.
Stack
)
self
.
setLayout
(
layout
)
# Signal/Slots connections
# self.basetype.activated.connect(self.changed_type_widget)
self
.
restricts
.
currentIndexChanged
.
connect
(
self
.
display
)
def
none_stack_ui
(
self
):
layout
=
QHBoxLayout
()
self
.
label
=
QLabel
(
self
.
tr
(
"No restrictions applied"
))
layout
.
addWidget
(
self
.
label
)
self
.
none_stack
.
setLayout
(
layout
)
def
choices_stack_ui
(
self
):
self
.
choices
=
QListWidget
()
self
.
add_button
=
QPushButton
(
self
.
tr
(
"+"
))
self
.
remove_button
=
QPushButton
(
self
.
tr
(
"-"
))
# Layouts
layout
=
QVBoxLayout
()
choices_layout
=
QVBoxLayout
()
choices_layout
.
addWidget
(
self
.
choices
)
buttons_layout
=
QHBoxLayout
()
buttons_layout
.
addWidget
(
self
.
add_button
)
buttons_layout
.
addWidget
(
self
.
remove_button
)
buttons_layout
.
addStretch
(
1
)
layout
.
addLayout
(
choices_layout
)
layout
.
addLayout
(
buttons_layout
)
self
.
choices_stack
.
setLayout
(
layout
)
# Signal/Slots connections
self
.
add_button
.
clicked
.
connect
(
self
.
__add_choice_clicked
)
self
.
remove_button
.
clicked
.
connect
(
self
.
__remove_choice_clicked
)
def
__add_choice_clicked
(
self
):
input_value
=
None
ok
=
False
min_value
=
NUMPY_TYPES
[
self
.
parent
.
selected_type
].
min
max_value
=
NUMPY_TYPES
[
self
.
parent
.
selected_type
].
max
if
self
.
parent
.
selected_type
==
InputType
.
get_type
(
InputType
.
STRING
):
input_value
,
ok
=
QInputDialog
.
getText
(
self
,
self
.
tr
(
"Input"
),
self
.
tr
(
"New Choice:"
)
)
elif
"int"
in
self
.
parent
.
selected_type
:
if
"64"
in
self
.
parent
.
selected_type
:
input_value
,
ok
=
Type64Dialog
.
getDialog
(
self
.
parent
.
selected_type
)
else
:
input_value
,
ok
=
QInputDialog
.
getInt
(
self
,
self
.
tr
(
"Input"
),
self
.
tr
(
"New Choice:"
),
1
,
min_value
,
max_value
,
)
elif
"float"
in
self
.
parent
.
selected_type
:
if
"64"
in
self
.
parent
.
selected_type
:
input_value
,
ok
=
Type64Dialog
.
getDialog
(
self
.
parent
.
selected_type
)
else
:
input_value
,
ok
=
QInputDialog
.
getDouble
(
self
,
self
.
tr
(
"Get double"
),
self
.
tr
(
"Value:"
),
1
,
min_value
,
max_value
,
10
,
)
if
ok
:
self
.
choices
.
addItem
(
str
(
input_value
))
def
__remove_choice_clicked
(
self
):
choices
=
self
.
choices
.
selectedItems
()
for
choice
in
choices
:
self
.
choices
.
takeItem
(
self
.
choices
.
row
(
choice
))
def
range_stack_ui
(
self
):
layout
=
QFormLayout
()
self
.
minimum_value
=
QDoubleSpinBox
()
self
.
maximum_value
=
QDoubleSpinBox
()
self
.
minimum_value
.
setMinimum
(
-
sys
.
float_info
.
max
)
self
.
minimum_value
.
setMaximum
(
sys
.
float_info
.
max
)
self
.
maximum_value
.
setMinimum
(
-
sys
.
float_info
.
max
)
self
.
maximum_value
.
setMaximum
(
sys
.
float_info
.
max
)
layout
.
addRow
(
self
.
tr
(
"Min"
),
self
.
minimum_value
)
layout
.
addRow
(
self
.
tr
(
"Max"
),
self
.
maximum_value
)
self
.
range_stack
.
setLayout
(
layout
)
def
display
(
self
,
i
):
self
.
Stack
.
setCurrentIndex
(
i
)
def
get_information
(
self
):
return
"ChoicesRangesWidget"
# def get_type(self):
# return self.parent.base
class
BoolWidget
(
QWidget
):
def
__init__
(
self
,
parent
=
None
):
super
(
BoolWidget
,
self
).
__init__
(
parent
)
# Widgets
self
.
label
=
QLabel
(
self
.
tr
(
"Default"
))
self
.
true_button
=
QRadioButton
(
self
.
tr
(
"True"
))
self
.
true_button
.
setChecked
(
True
)
self
.
false_button
=
QRadioButton
(
self
.
tr
(
"False"
))
# Layouts
layout
=
QHBoxLayout
()
layout
.
addWidget
(
self
.
label
)
layout
.
addWidget
(
self
.
true_button
)
layout
.
addWidget
(
self
.
false_button
)
self
.
setLayout
(
layout
)
def
get_information
(
self
):
return
self
.
true_button
.
isChecked
()
class
StackedWidget
(
QStackedWidget
):
def
__init__
(
self
,
parent
=
None
):
super
(
StackedWidget
,
self
).
__init__
(
parent
)
# members
self
.
sel
=
None
class
ParameterWidget
(
QWidget
):
"""Class holder for the parameter"""
dataChanged
=
pyqtSignal
()
def
__init__
(
self
,
parent
=
None
):
"""Constructor"""
super
(
ParameterWidget
,
self
).
__init__
(
parent
)
unwanted_basetypes
=
{
"complex64"
,
"complex128"
}
basetypes
=
json
.
loads
(
pkg_resources
.
resource_string
(
"beat.core.schema"
,
"common/1.json"
)
)[
"definitions"
][
"basetype"
][
"enum"
]
basetypes
=
[
i
for
i
in
basetypes
if
i
not
in
unwanted_basetypes
]
# Widgets
self
.
parameter_box
=
QGroupBox
(
self
.
tr
(
"Parameter"
))
self
.
name
=
QLineEdit
()
self
.
description
=
QLineEdit
()
self
.
basetype
=
QComboBox
()
self
.
basetype
.
addItems
(
basetypes
)
self
.
selected_type
=
basetypes
[
0
]
self
.
default
=
QLineEdit
()
# self.restricts = QComboBox()
# self.restricts.addItems([self.tr("None"), self.tr("Choices"), self.tr("Range")])
self
.
stacked_basetype
=
QStackedWidget
()
self
.
choices_range_widget
=
ChoicesRangeWidget
(
self
)
self
.
choices_widget
=
ChoicesWidget
(
self
)
self
.
bool_widget
=
BoolWidget
(
self
)
self
.
stacked_basetype
.
addWidget
(
self
.
choices_range_widget
)
self
.
stacked_basetype
.
addWidget
(
self
.
choices_widget
)
self
.
stacked_basetype
.
addWidget
(
self
.
bool_widget
)
# self.stacked_basetype2 = StackedWidget(self)
# self.choices_range_widget2 = ChoicesRangeWidget(self)
# self.choices_widget2 = ChoicesWidget()
# self.bool_widget2 = BoolWidget(self)
# self.stacked_basetype2.addWidget(self.choices_range_widget)
# self.stacked_basetype2.addWidget(self.choices_widget)
# self.stacked_basetype2.addWidget(self.bool_widget)
# self.stacked_basetype2.sel = self.selected_type
# Layouts
layout
=
QVBoxLayout
(
self
)
# QFormLayout for parameter setup
parameter_layout
=
QFormLayout
()
parameter_layout
.
addRow
(
self
.
tr
(
"Name:"
),
self
.
name
)
parameter_layout
.
addRow
(
self
.
tr
(
"Description:"
),
self
.
description
)
parameter_layout
.
addRow
(
self
.
tr
(
"Type:"
),
self
.
basetype
)
parameter_layout
.
addRow
(
self
.
tr
(
"Default:"
),
self
.
default
)
# parameter_layout.addRow(self.tr("Restrict to:"), self.restricts)
parameter_layout
.
addRow
(
self
.
tr
(
"Defaults/Restriction:"
),
self
.
stacked_basetype
)
# parameter_layout.addRow(self.tr("Defaults/Restriction:"), self.stacked_basetype2)
self
.
parameter_box
.
setLayout
(
parameter_layout
)
# Layouts Design
layout
.
addWidget
(
self
.
parameter_box
)
# Signal/Slots connections
# self.basetype.activated.connect(self.changed_type_widget)
self
.
basetype
.
currentIndexChanged
.
connect
(
self
.
changed_type_widget
)
# Change current index to update stacked widget
# self.basetype.setCurrentIndex(1)
self
.
name
.
textChanged
.
connect
(
self
.
updated
)
def
changed_type_widget
(
self
):
self
.
selected_type
=
self
.
basetype
.
currentText
()
print
(
"Type: {}"
.
format
(
self
.
selected_type
))
# self.stacked_basetype2.sel = self.selected_type
# print("Type: {}".format(self.stacked_basetype2.sel))
if
self
.
selected_type
==
InputType
.
get_type
(
InputType
.
BOOL
):
self
.
stacked_basetype
.
setCurrentIndex
(
2
)
elif
self
.
selected_type
==
InputType
.
get_type
(
InputType
.
STRING
):
self
.
stacked_basetype
.
setCurrentIndex
(
1
)
else
:
self
.
stacked_basetype
.
setCurrentIndex
(
0
)
def
get_current_type
(
self
):
return
self
.
basetype
.
currentText
()
def
updated
(
self
):
print
(
"Index: {}"
.
format
(
self
.
stacked_basetype
.
currentIndex
()))
print
(
"Widget: {}"
.
format
(
self
.
stacked_basetype
.
currentWidget
()))
print
(
"Info: {}"
.
format
(
self
.
stacked_basetype
.
currentWidget
().
get_information
())
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment