Как подключить несколько сигналов к одному слоту в QT / QML? - PullRequest
0 голосов
/ 15 сентября 2018

У меня есть пользовательский компонент панели инструментов, и я хочу, чтобы компоненты кнопки в нем излучали переключаемый сигнал. Я также хочу захватывать сигналы от всех кнопок в одном обработчике onToggled в компоненте панели инструментов верхнего уровня.

Я знаю, что это может быть достигнуто через Repeater + Component + VisualItemModel, но я нахожу это немного излишним.

Есть ли более простой способ?

Итак, еще раз, чтобы повторить. Текущий пример кода отлично работает , в этом нет ничего плохого. Моя проблема в том, что я нахожу это чрезвычайно сложным для небольшой проблемы, которую можно решить с помощью моего псевдокода (если бы в QML было что-то подобное)

Псевдокод:

// CustomButton emits onClicked(string name)
Rectangle {
  CustomButton {
      id: button2
      text: "Button1"
      name: "button1"
  }

  CustomButton {
      id: button2
      text: "Button2"
      name: "button2"
  }

  CustomButton {
      id: button3
      text: "Button3"
      name: "button3"
  }
}

Connections {
  target: button1, button2, button3
  onClicked: { console.log ("Button "+name+" pressed"); }
}

Текущий код:

ApplicationToolbar.qml

import QtQuick 2.0
import QtQuick.Layouts 1.11
import QtQuick.Controls 1.4
import "../Style"
import "../Widgets/Buttons"

Rectangle {
    id: toolbar
    Gradients { id: gradients }

    width: parent.width
    height: UIStyle.buttonHeight + 2*UIStyle.verticalSpacer
    gradient: storage.operationMode()==="online" ? gradients.onlineTabbarGradient : gradients.trainingTabbarGradient

    property int defaultItem : 0
    property VisualItemModel toolbarModel
    property var subtabs

    signal tabItemClicked(string tabid)

    Component {
        id: toolbarItem

        ButtonTab {
            height: toolbarModel.children[index].height
            selected: toolbarModel.children[index].selected
            iconsource: toolbarModel.children[index].iconsource
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    console.log ("toggled index "+index);
                    for (var i = 0; i < toolbarModel.count; i++) toolbarModel.children[i].selected = false;
                    toolbarModel.children[index].selected = true;
                    toolbar.tabItemClicked(toolbarModel.children[index].name);
                }
            }
        }
    }

    RowLayout {
        id: tabs
        anchors.bottom: parent.bottom
        anchors.left: parent.left
        anchors.leftMargin: UIStyle.horizontalSpacer

        spacing: UIStyle.horizontalSpacer/2

        Repeater {
            model: toolbarModel.count
            delegate: toolbarItem
        }
    }

    Component.onCompleted: {
        for (var i = 0; i < toolbarModel.count; i++) toolbarModel.children[i].selected = false;
        toolbarModel.children[defaultItem].selected = true
        toolbar.tabItemClicked(toolbarModel.children[defaultItem].name);
    }
}

ButtonTab.qml

import QtQuick 2.0
import QtQuick.Extras 1.4
import QtQuick.Layouts 1.11
import "../../Style"
import "../"

Rectangle {
    id: buttontab

    property string name
    property string iconsource: ""
    property bool selected: false

    Gradients { id: gradients }

    width: UIStyle.buttonWidth * 3
    height: selected ? UIStyle.buttonHeight * 1.25 : UIStyle.buttonHeight
    radius: UIStyle.cornerRadiusSmall
    // doesn't work
    //Layout.alignment: Qt.AlignBottom
    anchors.bottom: parent.bottom

    gradient: {
        if (!enabled) {
            gradients.disabledButtonGradient
        } else if (selected) {
            gradients.selectedTabButtonGradien
        } else {
            gradients.tabButtonGradient
        }
    }

    Image {
        source : buttontab.iconsource
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.verticalCenter: parent.verticalCenter
    }
}

1 Ответ

0 голосов
/ 17 сентября 2018

Вам не нужно VisualItemModel (что, кстати, было заменено ObjectModel), чтобы использовать Repeater, достаточно простого списка строк для текста кнопки, если вы можете жить с использованием индекса кнопкивместо его имени в слоте:

Row {
  Repeater {
    model: ["Button 1", "Button 2", "Button 3"]

    delegate: CustomButton {
      text: modelData
      onClicked: console.log("Button " + index + " pressed")
    }
  }
}

Если вам действительно нужно, чтобы кнопка также имела имя, вы все равно можете вернуться к списку объектов:

Row {
  Repeater {
    model: [{ text: "Button 1", name: "button1" },
            { text: "Button 2", name: "button2" },
            { text: "Button 3", name: "button3" }]

    delegate: CustomButton {
      text: modelData.text
      name: modelData.name
      onClicked: console.log("Button " + name + " pressed")
    }
  }
}
...