Beispiel #1
0
class JointStatePublisherGui(QWidget):
    def __init__(self, title, jsp, num_rows=0):
        super(JointStatePublisherGui, self).__init__()
        font = QFont("Helvetica", 9, QFont.Bold)
        self.hlayout = QHBoxLayout(self)
        vlayout = QVBoxLayout()
        glayout = QGridLayout()
        right_l_lauout = QVBoxLayout()
        self.listVeiw = QListWidget()
        self.checkbox = []
        self.value_line_edit = []
        self.sliders = []
        self.positions = []
        self.progressbars = []

        self.value_last = []

        speed_max = enviromnt_conf['joint_speed']
        slider_max = speed_max * 1000

        position_max = enviromnt_conf['joint_max_position']
        progress_max = position_max * 1000

        #create joints widget
        for i in range(0, num_rows):
            if config[i][0]:
                g_in_g = QGridLayout()
                checkbox = QCheckBox(config[i][1])
                checkbox.setFont(font)

                self.checkbox.append(checkbox)

                value_line_edit = QLineEdit()
                value_line_edit.setFont(font)
                value_line_edit.setText("0.0")

                self.value_line_edit.append(value_line_edit)

                display_lable = QLabel()
                display_lable.setFont(font)
                display_lable.setText("Position:")

                position_label = QLabel()
                position_label.setFont(font)
                position_label.setText("0.0")

                self.positions.append(position_label)

                position_progress_bar = QProgressBar()
                position_progress_bar.setMaximum(progress_max)
                position_progress_bar.setMinimum(-progress_max)
                position_progress_bar.setValue(0)

                self.progressbars.append(position_progress_bar)

                slider = QSlider()
                slider.setMaximum(slider_max)
                slider.setMinimum(-slider_max)
                slider.setOrientation(Qt.Horizontal)
                slider.valueChanged.connect(self.slider_value_changed)
                self.sliders.append(slider)

                g_in_g.addWidget(checkbox, 0, 0)
                g_in_g.addWidget(value_line_edit, 0, 1)
                g_in_g.addWidget(display_lable, 0, 2)
                g_in_g.addWidget(position_label, 0, 3)
                g_in_g.addWidget(slider, 1, 0, 1, 2)
                g_in_g.addWidget(position_progress_bar, 1, 2, 1, 2)

                glayout.addLayout(g_in_g, i, 0)

        #create v layout
        self.import_Btn = QPushButton('Import')
        self.import_Btn.setFont(font)
        self.import_Btn.clicked.connect(self.import_Btn_clecked)

        self.export_Btn = QPushButton('Export')
        self.export_Btn.setFont(font)
        self.export_Btn.clicked.connect(self.export_Btn_clicked)

        self.start_Btn = QPushButton("Start")
        self.start_Btn.setFont(font)
        self.start_Btn.clicked.connect(self.start_Btn_clicked)

        self.reset_Btn = QPushButton('Reset')
        self.reset_Btn.setFont(font)
        self.reset_Btn.clicked.connect(self.reset_Btn_clicked)

        self.record_Btn = QPushButton('Record')
        self.record_Btn.setFont(font)
        self.record_Btn.clicked.connect(self.record_Btn_clicked)

        self.replay_Btn = QPushButton('Repaly')
        self.replay_Btn.setFont(font)
        self.replay_Btn.clicked.connect(self.replay_Btn_clicked)

        self.delete_Btn = QPushButton("Delete")
        self.delete_Btn.setFont(font)
        self.delete_Btn.clicked.connect(self.delete_Btn_clicked)

        self.debug_Btn = QPushButton("Debug")
        self.debug_Btn.setFont(font)
        self.debug_Btn.clicked.connect(self.debug_Btn_clicked)

        vlayout.addWidget(self.import_Btn)
        vlayout.addWidget(self.export_Btn)
        vlayout.addWidget(self.start_Btn)
        vlayout.addWidget(self.reset_Btn)
        vlayout.addWidget(self.record_Btn)
        vlayout.addWidget(self.delete_Btn)
        vlayout.addWidget(self.replay_Btn)
        vlayout.addWidget(self.debug_Btn)

        self.master_url = QLineEdit("http://192.168.0.91:11311")
        self.master_url.setFont(font)

        self.master_ip = QLineEdit("192.168.0.91")
        self.master_ip.setFont(font)

        self.listVeiw.clicked.connect(self.listVeiw_clicked)
        self.listVeiw.currentRowChanged.connect(
            self.listVeiw_itemSelectionChanged)

        self.description = QTextEdit("")
        self.description.setFont(font)

        #self.description.setGeometry(0,100,100,500)

        right_l_lauout.addWidget(self.master_url)
        right_l_lauout.addWidget(self.master_ip)
        right_l_lauout.addWidget(self.listVeiw)
        right_l_lauout.addWidget(self.description)

        right_l_lauout.setStretch(0, 1)
        right_l_lauout.setStretch(1, 1)
        right_l_lauout.setStretch(2, 3)
        right_l_lauout.setStretch(3, 1)

        self.num_rows = len(self.checkbox)
        self.hlayout.addLayout(glayout)
        self.hlayout.addLayout(vlayout)
        self.hlayout.addLayout(right_l_lauout)
        self.setLayout(self.hlayout)

        self.callback_start = None
        self.callback_pause = None
        self.callback_record = None
        self.callback_reset = None
        self.callback_replay = None
        self.callback_replay_stop = None
        self.callback_delete = None
        self.callback_debug = None
        self.callback_import = None
        self.callback_export = None
        self.callback_list_clicked = None

        self.listVeiw_isClicked = False
        self.listVeiw_current_item = 0
        self.listVeiw_len = 0
        self.f = QFileDialog()

    def who_data_changed(self):
        for i in range(0, self.num_rows):
            value_last = self.value_line_edit[i].text()
            value_last = float(value_last) * 1000
            value = self.sliders[i].value()
            if value != value_last:
                return i

    def change_line_edit(self, change_index):
        value = self.sliders[change_index].value()
        value = float(value) / 1000
        value = str(value)
        self.value_line_edit[change_index].setText(value)

    def change_position_edit(self, change_index):
        value = self.progressbars[change_index].value()
        value += self.sliders[change_index].value()
        self.progressbars[change_index].setValue(value)

        self.positions[change_index].setText(str(float(value) / 1000))

    def reset_speed(self, change_index):
        self.sliders[change_index].setValue(0)

    def reset_speed_all(self):
        for i in range(0, self.num_rows):
            self.reset_speed(i)

    def set_speed(self, index, data):
        self.sliders[index].setValue(data)

    def import_Btn_clecked(self):
        self.file_path = self.f.getOpenFileName(caption='Import excel data',
                                                directory='',
                                                filter='*.xlsx',
                                                initialFilter='')
        self.file_path = self.file_path[0]
        if self.callback_import:
            self.callback_import()
        pass

    def export_Btn_clicked(self):
        self.file_path = self.f.getSaveFileName(caption='Save as excel data',
                                                directory='',
                                                filter='*.xlsx',
                                                initialFilter='')
        self.file_path = self.file_path[0]
        if self.callback_export:
            self.callback_export()
        pass

    def set_callback_start(self, func):
        self.callback_start = func

    def start_Btn_clicked(self):
        if self.start_Btn.text() == "Start":
            if self.callback_start:
                self.callback_start()
            self.start_Btn.setText("Pause")
        else:
            if self.callback_pause:
                self.callback_pause()
            self.start_Btn.setText("Start")

    def reset_Btn_clicked(self):
        self.reset_speed_all()
        self.reset_postion_all()

        if self.callback_reset:
            self.callback_reset()

    def replay_Btn_clicked(self):
        if self.replay_Btn.text() == "Replay":
            self.replay_Btn.setText("Stop")
            if self.callback_replay:
                self.callback_replay()
        else:
            self.replay_Btn.setText("Replay")
            if self.callback_replay_stop:
                self.callback_replay_stop()

    def debug_Btn_clicked(self):
        if self.callback_debug:
            self.callback_debug()

    def record_Btn_clicked(self):
        self.set_postion()
        self.listVeiw_len += 1
        if self.callback_record:
            self.callback_record()
        self.reset_speed_all()

    def listVeiw_itemSelectionChanged(self, index):
        self.listVeiw_isClicked = True
        self.listVeiw_current_item = index
        if self.callback_list_clicked:
            self.callback_list_clicked()

    def listVeiw_clicked(self, index):
        #print "index", index.row()
        if self.listVeiw_current_item != index.row():
            description_text = self.description.toPlainText()
            #self.listVeiw.item(self.listVeiw_current_item).setData(1,"123")
            #print self.listVeiw.item(self.listVeiw_current_item).data
        self.listVeiw_isClicked = True
        self.listVeiw_current_item = index.row()
        if self.callback_list_clicked:
            self.callback_list_clicked()

    def update_listView(self):
        print "update", self.listVeiw_len
        for i in range(0, self.listVeiw_len):
            view = self.listVeiw.item(i)
            view.setText(str(i))

    def get_listVeiw_current_item(self):
        return self.listVeiw_current_item

    def delete_Btn_clicked(self):
        if self.listVeiw_isClicked:
            print self.listVeiw_current_item
            self.listVeiw.removeItemWidget(
                self.listVeiw.takeItem(self.listVeiw_current_item))
            self.listVeiw_len -= 1
            if self.listVeiw_current_item != self.listVeiw_len:
                self.update_listView()
            if self.callback_delete:
                self.callback_delete()
            if self.listVeiw_current_item == 0:
                self.listVeiw_current_item = 0
            else:
                self.listVeiw_current_item -= 1

            self.listVeiw.setCurrentRow(self.listVeiw_current_item)
            if self.listVeiw_len == 0:
                self.listVeiw_isClicked = False

    def listView_add_item(self, index):
        self.listVeiw.addItem(str(index))

    def listView_inset_item(self, index, label):
        self.listVeiw.insertItem(index, str(label))

    def slider_value_changed(self, data):
        change_index = self.who_data_changed()
        self.change_line_edit(change_index)

    def get_speed(self):
        speed = []
        for i in range(0, self.num_rows):
            value = self.sliders[i].value()
            value = float(value) / 1000
            speed.append(value)
        return speed

    def get_position(self):
        position = []
        for i in range(0, self.num_rows):
            value = self.progressbars[i].value()
            value += self.sliders[i].value()
            value = float(value) / 1000
            position.append(value)
        return position

    def set_postion(self):
        for i in range(0, self.num_rows):
            self.change_position_edit(i)

    def set_positions(self, data):
        print len(data)
        for i in range(0, len(data)):
            self.progressbars[i].setValue(data[i] * 1000)
            self.positions[i].setText(str(data[i]))

    def reset_position(self, change_index):
        value = 0
        self.progressbars[change_index].setValue(value)

        self.positions[change_index].setText(str(float(value) / 1000))

    def reset_postion_all(self):
        for i in range(0, self.num_rows):
            self.reset_position(i)
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout, 'Sliders')

        graph_button = QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)
        self.graph_button = graph_button

        firstCol = QVBoxLayout()
        firstCol.addWidget(graph_button)

        sliderbox.addLayout(firstCol)

        self.sliders = []

        all_rows_layout = QVBoxLayout()
        chan_idx = 0
        for num_channels_row in self.settings['num_channels']:
            row_layout = QHBoxLayout()
            for i in range(num_channels_row):
                idx = chan_idx * 1

                slider_group = {
                    'slider_p': None,
                    'number_p': None,
                    'slider_v': None,
                    'number_v': None,
                    'on_off': None
                }

                layout_cluster = QVBoxLayout()
                slider_cluster = QHBoxLayout()
                label = QLabel()
                label.setText("Chan. %d" % (idx + 1))
                label.setAlignment(Qt.AlignCenter)
                layout_cluster.addWidget(label)
                for j in range(2):
                    layout = QVBoxLayout()
                    layout.setAlignment(Qt.AlignHCenter)

                    slider = QSlider(Qt.Vertical)
                    slider.setMinimum(0)
                    slider.setMaximum(255)
                    slider.setValue(
                        self.settings['valve_offsets'][chan_idx][j])
                    slider.setTickPosition(QSlider.TicksRight)
                    slider.setTickInterval(5)

                    spinbox = QSpinBox()
                    spinbox.setRange(0, 255)
                    spinbox.setValue(
                        self.settings['valve_offsets'][chan_idx][j])

                    slider.valueChanged.connect(spinbox.setValue)
                    spinbox.valueChanged.connect(slider.setValue)

                    cb_function_curr = lambda value, idx=idx: self.send_slider_value(
                        idx, value)
                    slider.valueChanged.connect(cb_function_curr)

                    label = QLabel()
                    label.setAlignment(Qt.AlignCenter)

                    if j == 0:
                        slider_group['slider_p'] = slider
                        slider_group['number_p'] = spinbox
                        label.setText("P")
                    else:
                        slider_group['slider_v'] = slider
                        slider_group['number_v'] = spinbox
                        label.setText("V")

                    labelmax = QLabel()
                    labelmax.setAlignment(Qt.AlignCenter)
                    labelmax.setText("255")

                    labelmin = QLabel()
                    labelmin.setAlignment(Qt.AlignCenter)
                    labelmin.setText("0")

                    layout.addWidget(label)
                    layout.addWidget(labelmax)
                    layout.addWidget(slider, Qt.AlignHCenter)
                    layout.addWidget(labelmin)
                    layout.addWidget(spinbox, Qt.AlignHCenter)
                    layout.setAlignment(slider, Qt.AlignHCenter)
                    layout.setAlignment(spinbox, Qt.AlignHCenter)

                    slider_cluster.addLayout(layout)

                on_button = QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][chan_idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(
                    lambda state, idx=idx: self.send_channel_state(idx, state))

                slider_group['on_off'] = on_button

                layout_cluster.addLayout(slider_cluster)
                layout_cluster.addWidget(on_button)

                row_layout.addLayout(layout_cluster)
                row_layout.addSpacing(20)

                self.sliders.append(slider_group)
                chan_idx += 1

            all_rows_layout.addLayout(row_layout)
        sliderbox.addLayout(all_rows_layout)
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout, 'Sliders')

        firstCol = QVBoxLayout()
        graph_button = QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)

        reset_button = QPushButton()
        reset_button.setCheckable(False)
        reset_button.setText("Reset")
        reset_button.clicked.connect(self.set_reset)

        self.graph_button = graph_button
        self.reset_button = reset_button

        firstCol.addWidget(graph_button)
        firstCol.addWidget(reset_button)

        firstCol.setAlignment(graph_button, Qt.AlignVCenter)
        firstCol.setAlignment(reset_button, Qt.AlignVCenter)

        zero_button = QPushButton()
        zero_button.setCheckable(False)
        zero_button.setText("Set All Zero")
        zero_button.clicked.connect(self.set_pressure_zero)
        self.zero_button = zero_button
        firstCol.addWidget(zero_button)
        firstCol.setAlignment(zero_button, Qt.AlignVCenter)

        transition_box = QVBoxLayout()
        label = QLabel()
        label.setAlignment(Qt.AlignCenter)
        label.setText("Transition Time")

        spinbox = QDoubleSpinBox()
        spinbox.setMinimum(0)
        spinbox.setMaximum(10)
        spinbox.setValue(self.settings['transitions'])
        spinbox.setDecimals(1)
        spinbox.setSingleStep(0.1)
        spinbox.setSuffix(" sec")

        spinbox.valueChanged.connect(self.set_transition_value)

        transition_box.addWidget(label)
        transition_box.addWidget(spinbox)
        transition_box.setAlignment(label, Qt.AlignBottom)
        transition_box.setAlignment(spinbox, Qt.AlignTop)
        firstCol.addLayout(transition_box)

        self.sliders = []
        sliderbox.addLayout(firstCol)

        all_rows_layout = QVBoxLayout()

        chan_idx = 0
        for num_channels_row in self.settings['num_channels']:
            row_layout = QHBoxLayout()
            for i in range(num_channels_row):
                idx = chan_idx * 1

                slider_group = {'slider': None, 'number': None, 'on_off': None}
                layout_cluster = QVBoxLayout()

                layout = QVBoxLayout()
                layout.setAlignment(Qt.AlignHCenter)

                slider = QSlider(Qt.Vertical)
                slider.setMinimum(self.settings['min_pressure'][idx] * 10.0)
                slider.setMaximum(self.settings['max_pressure'][idx] * 10.0)
                slider.setValue(0)
                slider.setTickPosition(QSlider.TicksRight)
                slider.setTickInterval(20)

                spinbox = QDoubleSpinBox()
                spinbox.setMinimum(self.settings['min_pressure'][idx])
                spinbox.setMaximum(self.settings['max_pressure'][idx])
                spinbox.setValue(0)
                spinbox.setDecimals(1)
                spinbox.setSingleStep(0.1)

                cb_function_curr = lambda value, idx=idx, slider=False: self.send_slider_value(
                    idx, value, slider)
                cb_function_curr2 = lambda value, idx=idx, slider=True: self.send_slider_value(
                    idx, value, slider)
                slider.valueChanged.connect(cb_function_curr2)
                spinbox.valueChanged.connect(cb_function_curr)

                labelmax = QLabel()
                labelmax.setAlignment(Qt.AlignCenter)
                labelmax.setText("%0.1f" %
                                 (self.settings['max_pressure'][idx]))

                labelmin = QLabel()
                labelmin.setAlignment(Qt.AlignCenter)
                labelmin.setText("%0.1f" %
                                 (self.settings['min_pressure'][idx]))

                layout.addWidget(labelmax)
                layout.addWidget(slider)
                layout.addWidget(labelmin)
                layout.addWidget(spinbox)

                layout.setAlignment(slider, Qt.AlignHCenter)
                layout.setAlignment(spinbox, Qt.AlignHCenter)

                label = QLabel()
                label.setText("Chan. %d" % (chan_idx + 1))
                label.setAlignment(Qt.AlignCenter)
                layout_cluster.addWidget(label)
                layout_cluster.addLayout(layout)

                slider_group['slider'] = slider
                slider_group['number'] = spinbox

                on_button = QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(
                    lambda state, idx=idx: self.send_channel_state(idx, state))

                slider_group['on_off'] = on_button

                layout_cluster.addWidget(on_button)

                row_layout.addLayout(layout_cluster)
                row_layout.addSpacing(20)

                self.sliders.append(slider_group)

                chan_idx += 1

            all_rows_layout.addLayout(row_layout)

        sliderbox.addLayout(all_rows_layout)
Beispiel #4
0
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout, 'Sliders')

        graph_button = QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)
        self.graph_button = graph_button

        firstCol = QVBoxLayout()
        firstCol.addWidget(graph_button)

        sliderbox.addLayout(firstCol)

        self.sliders = []

        all_rows_layout = QVBoxLayout()
        chan_idx = 0
        for num_channels_row in self.settings['num_channels']:
            row_layout = QHBoxLayout()
            for i in range(num_channels_row):
                idx = chan_idx * 1

                slider_group = {
                    'slider_p': None,
                    'number_p': None,
                    'slider_i': None,
                    'number_i': None,
                    'slider_d': None,
                    'number_d': None,
                    'on_off': None
                }

                layout_cluster = QVBoxLayout()
                slider_cluster = QHBoxLayout()
                label = QLabel()
                label.setText("Chan. %d" % (idx + 1))
                label.setAlignment(Qt.AlignCenter)
                layout_cluster.addWidget(label)
                for j in range(3):
                    layout = QVBoxLayout()
                    layout.setAlignment(Qt.AlignHCenter)

                    if j == 0:
                        maxrange = 1.0
                    elif j == 1:
                        maxrange = 10
                    elif j == 2:
                        maxrange = 10

                    slider = QSlider(Qt.Vertical)
                    slider.setMinimum(0)
                    slider.setMaximum(maxrange * 100)
                    slider.setValue(self.settings['pid_gains'][chan_idx][j] *
                                    100)
                    slider.setTickPosition(QSlider.TicksRight)
                    slider.setTickInterval(maxrange / 100.0)

                    spinbox = QDoubleSpinBox()
                    spinbox.setMinimum(0)
                    spinbox.setMaximum(maxrange)
                    spinbox.setValue(self.settings['pid_gains'][chan_idx][j])
                    spinbox.setDecimals(2)
                    spinbox.setSingleStep(maxrange / 100.0)

                    cb_function_number = lambda value, idx=idx, gain_idx=j, slider=False: self.send_slider_value(
                        idx, gain_idx, value, slider)
                    cb_function_slider = lambda value, idx=idx, gain_idx=j, slider=True: self.send_slider_value(
                        idx, gain_idx, value, slider)

                    slider.valueChanged.connect(cb_function_slider)
                    spinbox.valueChanged.connect(cb_function_number)

                    label = QLabel()
                    label.setAlignment(Qt.AlignCenter)

                    if j == 0:
                        slider_group['slider_p'] = slider
                        slider_group['number_p'] = spinbox
                        label.setText("P")
                    elif j == 1:
                        slider_group['slider_i'] = slider
                        slider_group['number_i'] = spinbox
                        label.setText("I")
                    elif j == 2:
                        slider_group['slider_d'] = slider
                        slider_group['number_d'] = spinbox
                        label.setText("D")

                    labelmax = QLabel()
                    labelmax.setAlignment(Qt.AlignCenter)
                    labelmax.setText("%0.1f" % (maxrange))

                    labelmin = QLabel()
                    labelmin.setAlignment(Qt.AlignCenter)
                    labelmin.setText("0")

                    layout.addWidget(label)
                    layout.addWidget(labelmax)
                    layout.addWidget(slider, Qt.AlignHCenter)
                    layout.addWidget(labelmin)
                    layout.addWidget(spinbox, Qt.AlignHCenter)
                    layout.setAlignment(slider, Qt.AlignHCenter)
                    layout.setAlignment(spinbox, Qt.AlignHCenter)

                    slider_cluster.addLayout(layout)

                on_button = QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][chan_idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(
                    lambda state, idx=idx: self.send_channel_state(idx, state))

                slider_group['on_off'] = on_button

                layout_cluster.addLayout(slider_cluster)
                layout_cluster.addWidget(on_button)

                row_layout.addLayout(layout_cluster)
                row_layout.addSpacing(20)

                self.sliders.append(slider_group)
                chan_idx += 1

            all_rows_layout.addLayout(row_layout)
        sliderbox.addLayout(all_rows_layout)
    def init_sliders(self):
        sliderbox = self._widget.findChild(QLayout,'Sliders')

        firstCol = QVBoxLayout()
        graph_button=QPushButton()
        graph_button.setCheckable(True)
        graph_button.setText("Graph Off")
        graph_button.toggle()
        graph_button.clicked.connect(self.set_graph_state)
        self.graph_button = graph_button

        reset_button=QPushButton()
        reset_button.setCheckable(False)
        reset_button.setText("Reset")
        reset_button.clicked.connect(self.set_reset)

        self.graph_button = graph_button
        self.reset_button = reset_button

        firstCol.addWidget(graph_button)
        firstCol.addWidget(reset_button)


        firstCol.addWidget(graph_button)
        firstCol.setAlignment(graph_button,Qt.AlignVCenter)

        zero_button=QPushButton()
        zero_button.setCheckable(False)
        zero_button.setText("Set All Zero")
        zero_button.clicked.connect(self.set_pressure_zero)
        self.zero_button = zero_button
        firstCol.addWidget(zero_button)
        firstCol.setAlignment(zero_button,Qt.AlignVCenter)



        transition_box = QVBoxLayout()
        label = QLabel()
        label.setAlignment(Qt.AlignCenter)
        label.setText("Transition Time")

        spinbox = QDoubleSpinBox()
        spinbox.setMinimum(0)
        spinbox.setMaximum(10)
        spinbox.setValue(self.settings['transitions'])
        spinbox.setDecimals(1)
        spinbox.setSingleStep(0.1)
        spinbox.setSuffix(" sec")

        spinbox.valueChanged.connect(self.set_transition_value)

        transition_box.addWidget(label)
        transition_box.addWidget(spinbox)
        transition_box.setAlignment(label,Qt.AlignBottom)
        transition_box.setAlignment(spinbox,Qt.AlignTop)
        firstCol.addLayout(transition_box)

        self.sliders = []
        sliderbox.addLayout(firstCol)

        all_rows_layout = QVBoxLayout()

        g_idx = 0

        for row in self.settings['gui_config']:
            num_groups_row = len(row)
            row_layout = QHBoxLayout()
            for gr_idx, s_group in enumerate(row): 
                g_channels = s_group['channels']
                g_layout = s_group['layout']

                if 'horiz' in g_layout:
                    group_layout = QHBoxLayout()
                else:
                    group_layout = QVBoxLayout()

                control_group = {'sliders': [], 'on_off': None}

                label = QLabel()
                label.setText("Group. %d"%(g_idx+1))
                label.setAlignment(Qt.AlignCenter)
                group_layout.addWidget(label)

                for c_idx, s_idx in enumerate(g_channels):
                    idx = s_idx*1
                    
                    slider_group={'slider':None, 'number':None}
                    
                    layout_cluster = QVBoxLayout()

                    labelfirst = QLabel()
                    labelfirst.setAlignment(Qt.AlignCenter)

                    labellast = QLabel()
                    labellast.setAlignment(Qt.AlignCenter)

                    layout = QVBoxLayout()

                    if 'diff' in g_layout and c_idx == 0:

                        sublayout=QHBoxLayout()

                        layout.setAlignment(Qt.AlignVCenter)

                        slider = QSlider(Qt.Horizontal)
                        slider.setMinimum(-100)
                        slider.setMaximum(100)
                        slider.setValue(0)
                        slider.setTickPosition(QSlider.TicksRight)
                        slider.setTickInterval(20)

                        spinbox = QDoubleSpinBox()
                        spinbox.setMinimum(-10)
                        spinbox.setMaximum(10)
                        spinbox.setValue(0)
                        spinbox.setDecimals(1)
                        spinbox.setSingleStep(0.1)

                        labellast.setText("%0.1f"%(10)) # These are flipped becasue of order
                        labelfirst.setText("%0.1f"%(-10))

                        max_label = labellast
                        min_label = labelfirst

                    else:
                        layout.setAlignment(Qt.AlignHCenter)

                        slider = QSlider(Qt.Vertical)
                        slider.setMinimum(self.settings['min_pressure'][idx]*10.0)
                        slider.setMaximum(self.settings['max_pressure'][idx]*10.0)
                        slider.setValue(0)
                        slider.setTickPosition(QSlider.TicksRight)
                        slider.setTickInterval(20)

                        spinbox = QDoubleSpinBox()
                        spinbox.setMinimum(self.settings['min_pressure'][idx])
                        spinbox.setMaximum(self.settings['max_pressure'][idx])
                        spinbox.setValue(0)
                        spinbox.setDecimals(1)
                        spinbox.setSingleStep(0.1)

                        labelfirst.setText("%0.1f"%(self.settings['max_pressure'][idx]))
                        labellast.setText("%0.1f"%(self.settings['min_pressure'][idx]))

                        max_label = labelfirst
                        min_label = labellast

                    
                    cb_function_number = lambda value, g_idx=g_idx, s_idx=c_idx, slider=False: self.send_slider_value(g_idx,s_idx,value,slider)
                    cb_function_slider = lambda value, g_idx=g_idx, s_idx=c_idx, slider=True: self.send_slider_value(g_idx,s_idx,value,slider)
                    slider.valueChanged.connect(cb_function_slider)
                    spinbox.valueChanged.connect(cb_function_number)
               

                    if 'diff' in g_layout and c_idx == 0:

                        sublayout.addWidget(labelfirst)
                        sublayout.addWidget(slider)
                        sublayout.addWidget(labellast)
                        layout.addWidget(spinbox)
                        layout.addLayout(sublayout)
                    else:
                        layout.addWidget(labelfirst)
                        layout.addWidget(slider)
                        layout.addWidget(labellast)
                        layout.addWidget(spinbox)

                    layout.setAlignment(slider, Qt.AlignHCenter)
                    layout.setAlignment(spinbox, Qt.AlignHCenter)

                    layout_cluster.addLayout(layout)

                    slider_group['slider'] = slider
                    slider_group['number'] = spinbox
                    slider_group['max_label'] = max_label
                    slider_group['min_label'] = min_label
                    control_group['sliders'].append(slider_group)

                    group_layout.addLayout(layout_cluster)

                on_button=QPushButton()
                on_button.setCheckable(True)
                on_button.setText("Off")

                if self.settings['channel_states'][idx]:
                    on_button.toggle()
                    on_button.setText("On")

                on_button.clicked.connect(lambda state, g_idx=g_idx: self.send_channel_state(g_idx,state))

                group_layout.addWidget(on_button)

                row_layout.addLayout(group_layout)
                row_layout.addSpacing(20)

                control_group['on_off'] = on_button
                self.sliders.append(control_group)

                g_idx+=1

            all_rows_layout.addLayout(row_layout)

        sliderbox.addLayout(all_rows_layout)
class WaypointWindow(QWidget):
    def __init__(self, active_aircrafts):
        super(WaypointWindow, self).__init__()
        self.setWindowTitle("Ground Control Station")
        self.adjustSize()
        self.move(200, 100)

        self.waypoint_plaintext_dict = {}
        self.main_layout = QHBoxLayout()
        self.progressbar_layout = QVBoxLayout()
        self.progressbar_layout.setAlignment(Qt.AlignTop)
        # Why we separate this is so that we can refresh the layout
        self.create_layout(active_aircrafts)

        self.main_layout.addLayout(self.progressbar_layout)
        self.setLayout(self.main_layout)

    def create_layout(self, active_aircrafts):
        for i in active_aircrafts:
            self.create_progressbar(i)

    def create_progressbar(self, aircraft_no):
        waypoint_layout = QVBoxLayout()
        waypoint_layout.setContentsMargins(0, 10, 0, 10)
        waypoint_header_layout = QHBoxLayout(
        )  # waypoint_header_layout will be nested inside waypoint_layout with the progress bar beneath it

        aircraft_label = QLabel('Aircraft ' + str(aircraft_no))
        self.waypoint_plaintext_dict['aircraft' +
                                     str(aircraft_no)] = QPlainTextEdit()
        self.waypoint_plaintext_dict.get('aircraft' +
                                         str(aircraft_no)).setMaximumHeight(40)
        self.waypoint_plaintext_dict.get('aircraft' +
                                         str(aircraft_no)).setReadOnly(True)

        self.waypoint_plaintext_dict[
            'aircraftlink' + str(aircraft_no)] = QPlainTextEdit("Telegram")
        self.waypoint_plaintext_dict.get('aircraftlink' +
                                         str(aircraft_no)).setMaximumHeight(40)
        self.waypoint_plaintext_dict.get('aircraftlink' +
                                         str(aircraft_no)).setMaximumWidth(100)

        self.waypoint_plaintext_dict.get('aircraftlink' +
                                         str(aircraft_no)).setReadOnly(True)

        self.waypoint_plaintext_dict['progress_bar_aircraft' +
                                     str(aircraft_no)] = QProgressBar()

        waypoint_header_layout.addWidget(aircraft_label)
        waypoint_header_layout.addWidget(
            self.waypoint_plaintext_dict['aircraft' + str(aircraft_no)])
        waypoint_header_layout.addWidget(
            self.waypoint_plaintext_dict['aircraftlink' + str(aircraft_no)])
        waypoint_layout.addLayout(waypoint_header_layout)
        waypoint_layout.addWidget(
            self.waypoint_plaintext_dict['progress_bar_aircraft' +
                                         str(aircraft_no)])

        self.progressbar_layout.addLayout(waypoint_layout)

    def remove(self, layout):
        for i in reversed(range(layout.count())):
            child = layout.takeAt(0)
            if child.widget():
                child.widget().deleteLater()
            if child.layout():
                self.remove(child.layout())

    def shutdown(self):
        self.close()