Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
cs
gui
4uhv
Commits
024781f0
Commit
024781f0
authored
Sep 09, 2021
by
Giacomo Strangolino
Browse files
ported to cumbia
parent
dafe63d2
Changes
8
Hide whitespace changes
Inline
Side-by-side
4uhv.pro
View file @
024781f0
include
(
/
usr
/
local
/
qtango
/
include
/
qtango6
/
qtango
.
pri
)
isEmpty
(
CUMBIA_ROOT
)
{
CUMBIA_ROOT
=/
usr
/
local
/
cumbia
-
libs
}
include
(
$$
{
CUMBIA_ROOT
}
/
include
/
quapps
/
quapps
.
pri
)
TEMPLATE
=
app
QT
+=
CONFIG
+=
#
CONFIG
+=
debug
|
release
DEFINES
+=
QT_NO_DEBUG_OUTPUT
OBJECTS_DIR
=
obj
#
RESOURCES
+=
#
RESOURCES
+=
SOURCES
+=
src
/
main
.
cpp
\
src
/
4
uhv
.
cpp
\
...
...
@@ -20,8 +16,67 @@ SOURCES += src/main.cpp \
HEADERS
+=
src
/
4
uhv
.
h
\
src
/
channel
.
h
FORMS
=
src
/
4
uhv
.
ui
\
src
/
channel
.
ui
#
cuuimake
runs
uic
#
FORMS
=
src
/
4
uhv
.
ui
\
#
src
/
channel
.
ui
#
#
but
we
need
to
include
ui_xxxx
.
h
file
amongst
the
headers
#
in
order
to
be
recompiled
when
it
changes
#
HEADERS
+=
\
ui_4uhv
.
h
\
ui_channel
.
h
#
-
ui
:
where
to
find
cuuimake
ui_
*.
h
files
#
since
FORMS
is
not
used
#
-
src
:
where
to
find
headers
included
by
#
ui_
*.
h
(
e
.
g
.
for
custom
widget
promoted
#
from
the
Qt
designer
)
#
INCLUDEPATH
+=
ui
src
TARGET
=
FourUHV
-
gui
!
wasm
-
emscripten
{
TARGET
=
bin
/
$$
{
TARGET
}
}
else
{
TARGET
=
wasm
/
$$
{
TARGET
}
}
#
#
make
install
works
if
INSTALL_DIR
is
given
to
qmake
#
!
isEmpty
(
INSTALL_DIR
)
{
wasm
-
emscripten
{
inst
.
files
=
wasm
/*
} else {
inst.files = $${TARGET}
}
inst.path = $${INSTALL_DIR}
INSTALLS += inst
message("-")
message("INSTALLATION")
message(" execute `make install` to install '$PROJECT_NAME$' under $${INSTALL_DIR} ")
message("-")
} else {
message("-")
message("INSTALLATION")
message(" call qmake INSTALL_DIR=/usr/local/bin to install $PROJECT_NAME$ later with `make install` ")
message("-")
}
# unix:LIBS += -L. -lmylib
# unix:INCLUDEPATH += . ../../src
message("-")
message("NOTE")
message("You need to run cuuimake in order to build the project")
message("-")
message(" cuuimake --show-config to see cuuimake configuration options")
message(" cuuimake --configure to configure cuuimake")
message(" cuuimake -jN to execute cuuimake and then make -jN")
message(" cuuimake --make to run cuuimake and then make")
message("-")
TARGET
=
bin
/
FourUHV
-
gui
QMAKE_POST_LINK
=
$
(
STRIP
)
$
(
TARGET
)
src/4uhv.cpp
View file @
024781f0
#include "4uhv.h"
// cumbia
#include <cumbiapool.h>
#include <cuserviceprovider.h>
#include <cumacros.h>
#include <quapps.h>
// cumbia
#include "ui_4uhv.h"
#include "channel.h"
#include <tango.h>
#include <QMessageBox>
#include <QGridLayout>
#include <TPushButton>
// #include <TPushButton>
#include <qubutton.h>// TPushButton is mapped to QuButton // ## added by qumbiaprojectwizard
#include <QGroupBox>
#include <QtDebug>
#include <quwatcher.h>
FourUHV
::
FourUHV
(
QWidget
*
parent
)
:
QWidget
(
parent
),
ui
(
new
Ui
::
FourUHV
)
{
ui
->
setupUi
(
this
);
if
(
qApp
->
arguments
().
size
()
>
1
)
{
QString
device
=
qApp
->
arguments
().
at
(
1
);
QStringList
parts
;
std
::
vector
<
std
::
string
>
list
;
Tango
::
Database
*
db
=
new
Tango
::
Database
();
Tango
::
DbData
db_data
;
db_data
.
push_back
(
Tango
::
DbDatum
(
"power_supply"
));
try
{
db
->
get_property
(
"vacuum"
,
db_data
);
db_data
[
0
]
>>
list
;
for
(
size_t
i
=
0
;
i
<
list
.
size
();
i
++
)
{
parts
=
QString
::
fromStdString
(
list
.
at
(
i
)).
split
(
":"
);
if
(
parts
.
size
()
>=
3
&&
device
==
parts
.
first
())
{
for
(
int
ch
=
1
;
ch
<
parts
.
size
();
ch
++
)
if
(
parts
[
ch
].
compare
(
"none"
,
Qt
::
CaseInsensitive
)
!=
0
)
m_chSensorMap
[
ch
]
=
parts
[
ch
];
}
}
}
catch
(
Tango
::
DevFailed
&
e
)
{
perr
(
"4uhv: error getting power_supply property from
\"
vacuum
\"
object"
);
QMessageBox
::
critical
(
this
,
"Error getting property from database"
,
"4uhv: error getting power_supply property from
\"
vacuum
\"
object"
);
}
}
int
r
=
0
,
c
=
0
;
QGridLayout
*
glo
=
new
QGridLayout
(
ui
->
contentsWidget
);
foreach
(
int
ch
,
m_chSensorMap
.
keys
())
{
Channel
*
channel
=
new
Channel
(
ui
->
contentsWidget
);
channel
->
findChild
<
QLabel
*>
(
"lChannel"
)
->
setText
(
QString
(
"Channel %1 - %2"
)
.
arg
(
ch
).
arg
(
m_chSensorMap
[
ch
].
section
(
'/'
,
-
1
,
-
1
)));
foreach
(
QWidget
*
w
,
channel
->
findChildren
<
QWidget
*>
())
{
if
(
w
->
metaObject
()
->
indexOfProperty
(
"source"
)
>
-
1
)
w
->
setProperty
(
"source"
,
QString
(
w
->
property
(
"point"
).
toString
()).
arg
(
ch
));
if
(
w
->
metaObject
()
->
indexOfProperty
(
"targets"
)
>
-
1
)
w
->
setProperty
(
"targets"
,
QString
(
w
->
property
(
"point"
).
toString
()).
arg
(
ch
));
}
//////////////////////////////////////////////////////////////
//
// hide Threshold settings for now
channel
->
findChild
<
QGroupBox
*>
(
"gbHighTh"
)
->
setHidden
(
true
);
channel
->
findChild
<
QGroupBox
*>
(
"gbLowTh"
)
->
setHidden
(
true
);
//
///////////////////////////////////////////////////////////////
glo
->
addWidget
(
channel
,
r
,
c
%
2
,
1
,
1
);
if
(
c
==
1
)
{
c
=
0
;
r
++
;
}
else
c
++
;
FourUHV
::
FourUHV
(
CumbiaPool
*
cumbia_pool
,
QWidget
*
parent
)
:
QWidget
(
parent
)
{
// cumbia
CuModuleLoader
mloader
(
cumbia_pool
,
&
m_ctrl_factory_pool
,
&
m_log_impl
);
cu_pool
=
cumbia_pool
;
ui
=
new
Ui
::
FourUHV
;
ui
->
setupUi
(
this
,
cu_pool
,
m_ctrl_factory_pool
);
foreach
(
QGroupBox
*
gb
,
channel
->
findChild
<
QTabWidget
*>
()
->
widget
(
1
)
->
findChildren
<
QGroupBox
*>
())
connect
(
gb
->
findChild
<
TPushButton
*>
(),
SIGNAL
(
clicked
()),
this
,
SLOT
(
applyThresholdClicked
()));
// mloader.modules() to get the list of loaded modules
// cumbia
if
(
qApp
->
arguments
().
size
()
>
1
)
{
m_dev
=
qApp
->
arguments
().
at
(
1
);
Qu1TWatcher
*
spw
=
new
Qu1TWatcher
(
this
,
cu_pool
,
m_ctrl_factory_pool
);
connect
(
spw
,
SIGNAL
(
newData
(
const
CuData
&
)),
this
,
SLOT
(
onPsListReady
(
const
CuData
&
)));
spw
->
setSource
(
"tango://#vacuum#power_supply"
);
}
}
FourUHV
::~
FourUHV
()
{
FourUHV
::~
FourUHV
()
{
delete
ui
;
}
void
FourUHV
::
applyThresholdClicked
()
{
QString
onam
=
sender
()
->
objectName
();
if
(
sender
()
->
objectName
()
.
startsWith
(
"tpbApplyThHigh"
))
const
QString
&
onam
=
sender
()
->
objectName
();
if
(
onam
.
startsWith
(
"tpbApplyThHigh"
))
findChild
<
QGroupBox
*>
(
""
);
}
void
FourUHV
::
onPsListReady
(
const
CuData
&
da
)
{
if
(
da
.
B
(
"err"
))
{
}
else
{
std
::
vector
<
std
::
string
>
list
=
da
[
"value"
].
toStringVector
();
for
(
size_t
i
=
0
;
i
<
list
.
size
();
i
++
)
{
QStringList
parts
=
QString
::
fromStdString
(
list
.
at
(
i
)).
split
(
":"
);
if
(
parts
.
size
()
>=
3
&&
m_dev
==
parts
.
first
())
{
for
(
int
ch
=
1
;
ch
<
parts
.
size
();
ch
++
)
if
(
parts
[
ch
].
compare
(
"none"
,
Qt
::
CaseInsensitive
)
!=
0
)
m_chSensorMap
[
ch
]
=
parts
[
ch
];
}
}
int
r
=
0
,
c
=
0
;
QGridLayout
*
glo
=
new
QGridLayout
(
ui
->
contentsWidget
);
foreach
(
int
ch
,
m_chSensorMap
.
keys
())
{
Channel
*
channel
=
new
Channel
(
ui
->
contentsWidget
,
cu_pool
,
m_ctrl_factory_pool
);
channel
->
findChild
<
QLabel
*>
(
"lChannel"
)
->
setText
(
QString
(
"Channel %1 - %2"
)
.
arg
(
ch
).
arg
(
m_chSensorMap
[
ch
].
section
(
'/'
,
-
1
,
-
1
)));
foreach
(
QWidget
*
w
,
channel
->
findChildren
<
QWidget
*>
())
{
if
(
w
->
metaObject
()
->
indexOfProperty
(
"source"
)
>
-
1
)
{
const
QString
&
s
=
w
->
property
(
"point"
).
toString
();
if
(
s
.
contains
(
"%1"
))
w
->
setProperty
(
"source"
,
QString
(
s
).
arg
(
ch
));
}
if
(
w
->
metaObject
()
->
indexOfProperty
(
"target"
)
>
-
1
)
{
const
QString
&
t
=
w
->
property
(
"point"
).
toString
();
if
(
t
.
contains
(
"%1"
))
w
->
setProperty
(
"target"
,
QString
(
t
).
arg
(
ch
));
}
}
channel
->
findChild
<
QGroupBox
*>
(
"gbHighTh"
)
->
setHidden
(
true
);
channel
->
findChild
<
QGroupBox
*>
(
"gbLowTh"
)
->
setHidden
(
true
);
glo
->
addWidget
(
channel
,
r
,
c
%
2
,
1
,
1
);
if
(
c
==
1
)
{
c
=
0
;
r
++
;
}
else
c
++
;
foreach
(
QGroupBox
*
gb
,
channel
->
findChild
<
QTabWidget
*>
()
->
widget
(
1
)
->
findChildren
<
QGroupBox
*>
())
connect
(
gb
->
findChild
<
QuButton
*>
(),
SIGNAL
(
clicked
()),
this
,
SLOT
(
applyThresholdClicked
()));
}
}
}
src/4uhv.h
View file @
024781f0
#ifndef FourUHV_H
#define FourUHV_H
// cumbia
#include <qulogimpl.h>
#include <cucontrolsfactorypool.h>
class
CumbiaPool
;
class
CuData
;
// cumbia
#include <QWidget>
#include <QMap>
...
...
@@ -13,7 +20,7 @@ class FourUHV : public QWidget
Q_OBJECT
public:
explicit
FourUHV
(
QWidget
*
parent
=
0
);
explicit
FourUHV
(
CumbiaPool
*
cu_p
,
QWidget
*
parent
=
0
);
~
FourUHV
();
private:
...
...
@@ -23,6 +30,16 @@ private:
private
slots
:
void
applyThresholdClicked
();
void
onPsListReady
(
const
CuData
&
da
);
private:
// cumbia
CumbiaPool
*
cu_pool
;
QuLogImpl
m_log_impl
;
CuControlsFactoryPool
m_ctrl_factory_pool
;
// cumbia
QString
m_dev
;
};
#endif // FourUHV_H
src/4uhv.ui
View file @
024781f0
...
...
@@ -49,14 +49,14 @@
</widget>
</item>
<item
row=
"2"
column=
"0"
>
<widget
class=
"
T
Label"
name=
"tLabel_11"
>
<widget
class=
"
Qu
Label"
name=
"tLabel_11"
>
<property
name=
"source"
>
<string>
$1/state
</string>
</property>
</widget>
</item>
<item
row=
"2"
column=
"1"
>
<widget
class=
"
T
Label"
name=
"tLabel_12"
>
<widget
class=
"
Qu
Label"
name=
"tLabel_12"
>
<property
name=
"source"
>
<string>
$1/status
</string>
</property>
...
...
@@ -67,14 +67,9 @@
<layoutdefault
spacing=
"6"
margin=
"11"
/>
<customwidgets>
<customwidget>
<class>
TLabel
</class>
<extends>
ELabel
</extends>
<header>
TLabel
</header>
</customwidget>
<customwidget>
<class>
ELabel
</class>
<class>
QuLabel
</class>
<extends>
QLabel
</extends>
<header>
e
label.h
</header>
<header>
qu
label.h
</header>
</customwidget>
</customwidgets>
<resources/>
...
...
src/channel.cpp
View file @
024781f0
#include "channel.h"
#include "ui_channel.h"
Channel
::
Channel
(
QWidget
*
parent
)
:
QWidget
(
parent
),
ui
(
new
Ui
::
Channel
)
{
ui
->
setupUi
(
this
);
Channel
::
Channel
(
QWidget
*
parent
,
CumbiaPool
*
cu_p
,
const
CuControlsFactoryPool
&
fp
)
:
QWidget
(
parent
)
{
ui
=
new
Ui
::
Channel
;
ui
->
setupUi
(
this
,
cu_p
,
fp
);
}
Channel
::~
Channel
()
{
delete
ui
;
}
src/channel.h
View file @
024781f0
...
...
@@ -2,6 +2,9 @@
#define CHANNEL_H
#include <QWidget>
#include <cucontrolsfactorypool.h>
class
CumbiaPool
;
namespace
Ui
{
class
Channel
;
...
...
@@ -12,11 +15,14 @@ class Channel : public QWidget
Q_OBJECT
public:
explicit
Channel
(
QWidget
*
parent
=
0
);
explicit
Channel
(
QWidget
*
parent
,
CumbiaPool
*
cu_p
,
const
CuControlsFactoryPool
&
fp
);
~
Channel
();
private:
Ui
::
Channel
*
ui
;
CumbiaPool
*
cu_pool
;
CuControlsFactoryPool
m_ctrl_fpool
;
};
#endif // CHANNEL_H
src/channel.ui
View file @
024781f0
...
...
@@ -7,7 +7,7 @@
<x>
0
</x>
<y>
0
</y>
<width>
375
</width>
<height>
41
1
</height>
<height>
41
6
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
...
...
@@ -41,7 +41,7 @@
</attribute>
<layout
class=
"QGridLayout"
name=
"gridLayout_4"
>
<item
row=
"4"
column=
"0"
colspan=
"2"
>
<widget
class=
"
T
Table"
name=
"tTable"
>
<widget
class=
"
Qu
Table"
name=
"tTable"
>
<property
name=
"numRows"
>
<number>
5
</number>
</property>
...
...
@@ -82,7 +82,7 @@
</widget>
</item>
<item
row=
"3"
column=
"1"
>
<widget
class=
"
TPush
Button"
name=
"tPushButton_2"
>
<widget
class=
"
Qu
Button"
name=
"tPushButton_2"
>
<property
name=
"text"
>
<string>
Off
</string>
</property>
...
...
@@ -95,7 +95,7 @@
</widget>
</item>
<item
row=
"3"
column=
"0"
>
<widget
class=
"
TPush
Button"
name=
"tPushButton"
>
<widget
class=
"
Qu
Button"
name=
"tPushButton"
>
<property
name=
"text"
>
<string>
On
</string>
</property>
...
...
@@ -118,10 +118,7 @@
</widget>
</item>
<item
row=
"2"
column=
"1"
>
<widget
class=
"TLabel"
name=
"tLabel_3"
>
<property
name=
"source"
>
<string/>
</property>
<widget
class=
"QuLabel"
name=
"tLabel_3"
>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/Current%1
</string>
</property>
...
...
@@ -138,17 +135,14 @@
</widget>
</item>
<item
row=
"1"
column=
"1"
>
<widget
class=
"TLabel"
name=
"tLabel_2"
>
<property
name=
"source"
>
<string/>
</property>
<widget
class=
"QuLabel"
name=
"tLabel_2"
>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/Pressure%1
</string>
</property>
</widget>
</item>
<item
row=
"0"
column=
"1"
>
<widget
class=
"
T
Label"
name=
"tLabel"
>
<widget
class=
"
Qu
Label"
name=
"tLabel"
>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/Voltage%1
</string>
</property>
...
...
@@ -161,21 +155,8 @@
<string>
Expert
</string>
</attribute>
<layout
class=
"QGridLayout"
name=
"gridLayout_5"
>
<item
row=
"5"
column=
"0"
>
<spacer
name=
"spacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
65
</height>
</size>
</property>
</spacer>
</item>
<item
row=
"3"
column=
"2"
>
<widget
class=
"
TPush
Button"
name=
"tPushButton_7"
>
<widget
class=
"
Qu
Button"
name=
"tPushButton_7"
>
<property
name=
"text"
>
<string>
Step
</string>
</property>
...
...
@@ -184,18 +165,28 @@
</property>
</widget>
</item>
<item
row=
"
3
"
column=
"1"
>
<widget
class=
"
TPush
Button"
name=
"tPushButton_
6
"
>
<item
row=
"
2
"
column=
"1"
>
<widget
class=
"
Qu
Button"
name=
"tPushButton_
4
"
>
<property
name=
"text"
>
<string>
Fix
</string>
<string>
Fix
5000
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/Fixed%1(true)
</string>
<string>
$1/VTarget%1(5)
</string>
</property>
</widget>
</item>
<item
row=
"4"
column=
"2"
>
<widget
class=
"QuButton"
name=
"tPushButton_9"
>
<property
name=
"text"
>
<string>
Start
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/Protect%1(false)
</string>
</property>
</widget>
</item>
<item
row=
"2"
column=
"2"
>
<widget
class=
"
TPush
Button"
name=
"tPushButton_5"
>
<widget
class=
"
Qu
Button"
name=
"tPushButton_5"
>
<property
name=
"text"
>
<string>
Fix7000
</string>
</property>
...
...
@@ -204,13 +195,13 @@
</property>
</widget>
</item>
<item
row=
"
2
"
column=
"
0
"
>
<widget
class=
"
TPush
Button"
name=
"tPushButton_
3
"
>
<item
row=
"
4
"
column=
"
1
"
>
<widget
class=
"
Qu
Button"
name=
"tPushButton_
8
"
>
<property
name=
"text"
>
<string>
Fix3000
</string>
<string>
Protect
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/
VTarget%1(3
)
</string>
<string>
$1/
Protect%1(true
)
</string>
</property>
</widget>
</item>
...
...
@@ -237,55 +228,28 @@
</widget>
</item>
<item
row=
"0"
column=
"1"
>
<widget
class=
"TLabel"
name=
"tLabel_8"
>
<property
name=
"source"
>
<string/>
</property>
</widget>
<widget
class=
"QuLabel"
name=
"tLabel_8"
/>
</item>
<item
row=
"1"
column=
"0"
>
<widget
class=
"
T
LineEdit"
name=
"LowThr1"
/>
<widget
class=
"
Qu
LineEdit"
name=
"LowThr1"
/>
</item>
<item
row=
"1"
column=
"1"
>
<widget
class=
"
TPush
Button"
name=
"tpbApplyLow"
>
<widget
class=
"
Qu
Button"
name=
"tpbApplyLow"
>
<property
name=
"text"
>
<string>
Apply
</string>
</property>
<property
name=
"targets"
>
<string>
;
</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item
row=
"2"
column=
"1"
>
<widget
class=
"TPushButton"
name=
"tPushButton_4"
>
<property
name=
"text"
>
<string>
Fix5000
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/VTarget%1(5)
</string>
</property>
</widget>
</item>
<item
row=
"4"
column=
"2"
>
<widget
class=
"TPushButton"
name=
"tPushButton_9"
>
<property
name=
"text"
>
<string>
Start
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/Protect%1(false)
</string>
</property>
</widget>
</item>
<item
row=
"4"
column=
"1"
>
<widget
class=
"TPushButton"
name=
"tPushButton_8"
>
<item
row=
"3"
column=
"1"
>
<widget
class=
"QuButton"
name=
"tPushButton_6"
>
<property
name=
"text"
>
<string>
Protect
</string>
<string>
Fix
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/
Protect
%1(true)
</string>
<string>
$1/
Fixed
%1(true)
</string>
</property>
</widget>
</item>
...
...
@@ -312,24 +276,17 @@
</widget>
</item>
<item
row=
"0"
column=
"1"
>
<widget
class=
"TLabel"
name=
"tLabel_7"
>
<property
name=
"source"
>
<string/>
</property>
</widget>
<widget
class=
"QuLabel"
name=
"tLabel_7"
/>
</item>
<item
row=
"1"
column=
"0"
>
<widget
class=
"
T
LineEdit"
name=
"HighThr1"
/>
<widget
class=
"
Qu
LineEdit"
name=
"HighThr1"
/>
</item>
<item
row=
"1"
column=
"1"
>
<widget
class=
"
TPush
Button"
name=
"tpbApplyHigh"
>
<widget
class=
"
Qu
Button"
name=
"tpbApplyHigh"
>
<property
name=
"text"
>
<string>
Apply
</string>
</property>
<property
name=
"targets"
>
<string/>
</property>
<property
name=
"confirmNeeded"
>
<property
name=
"confirmNeeded"
stdset=
"0"
>
<bool>
true
</bool>
</property>
</widget>
...
...
@@ -337,6 +294,16 @@
</layout>
</widget>
</item>
<item
row=
"2"
column=
"0"
>
<widget
class=
"QuButton"
name=
"tPushButton_3"
>
<property
name=
"text"
>
<string>
Fix3000
</string>
</property>
<property
name=
"point"
stdset=
"0"
>
<string>
$1/VTarget%1(3)
</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
...
...
@@ -345,35 +312,30 @@
</widget>
<customwidgets>
<customwidget>
<class>
T
Label
</class>
<extends>
E
Label
</extends>
<header>
TL
abel
</header>
<class>
Qu
Label
</class>
<extends>
Q
Label
</extends>
<header>
qul
abel
.h
</header>