PySide2绑定模型到vi

2024-05-17 02:34:45 发布

您现在位置:Python中文网/ 问答频道 /正文

希望有人能帮我,因为我在网上找不到任何有用的东西。你知道吗

我正在为一个人工智能项目构建一个简单的GUI,并使用PySide2和QML。我已经设法理解了如何将函数绑定到按钮并使其工作。但我似乎不知道如何从python的字符串列表填充组合框(然后在python中使用选择)。我知道它和属性和模型有关,但我不能让它工作。你知道吗

下面是我的python代码:


import multiprocessing as mp
import sys

import mido
from Fuzzy.aidrummer import AiDrummer

from PySide2.QtWidgets import QApplication
from PySide2.QtQuick import QQuickView
from PySide2.QtCore import QUrl, Slot, QObject, Property, Signal

def run():
    d = AiDrummer('playback', file='../Music/28 coltrane 2.mid', play_instrument='yes', instrument_port='VirtualMIDISynth #1 0',
                  out_port='strike 3', visualize=True)
    d.run()


class Api(QObject):
    proc = None

    def __init__(self):
        QObject.__init__(self)
        self._midi_out = mido.get_output_names()
        print(self._midi_out)
        self._midi_in = mido.get_input_names()

    @Slot()
    def play(self):
        self.proc = mp.Process(target=run)
        self.proc.start()

    @Slot()
    def stop(self):
        try:
            assert isinstance(self.proc, mp.Process)
            self.proc.kill()
        except:
            return

    def read_midi_out(self):
        return self._midi_out

    def set_midi_out(self, val):
        self._midi_out = val

    @Signal
    def midi_out_changed(self):
        pass

    midi_out = Property(list, read_midi_out, set_midi_out, notify=midi_out_changed)


if __name__ == '__main__':
    app = QApplication([])
    view = QQuickView()
    view.setResizeMode(QQuickView.SizeRootObjectToView)
    url = QUrl("main.qml")

    api = Api()

    view.setSource(url)
    view.rootContext().setContextProperty('api', api)

    sys.exit(app.exec_())

还有我的主.qml(带模型的组合框靠近底部):

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.13
import QtQuick.Controls.Material 2.0

Window {
    id: window
    visible: true
    width: 980
    height: 700
    title: qsTr("AI Drummer")

    Rectangle {
        id: rectangle1
        color: "#191919"
        anchors.rightMargin: 0
        anchors.bottomMargin: 0
        anchors.leftMargin: 0
        anchors.topMargin: 0
        anchors.fill: parent
        clip: true
        rotation: 0

        Rectangle {
            id: rectangle
            x: 711
            width: 400
            height: 200
            color: "#3a3a3a"
            anchors.top: parent.top
            anchors.topMargin: -33
            anchors.right: parent.right
            anchors.rightMargin: -131
            rotation: 45
            clip: true
            Material.theme: Material.Dark
            Material.accent: Material.DeepOrange
        }

        RoundButton {
            id: playButton
            x: 356
            y: 632
            width: 100
            text: "Play"
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 28
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: 70
            onClicked: { api.play()}
        }

        RoundButton {
            id: stopButton
            x: 462
            y: 632
            width: 100
            text: "Stop"
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 28
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: -70
            onClicked: { api.stop()}
        }

        ComboBox {
            id: instrument_port
            x: 214
            y: 637
            width: 120
            height: 30
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: 176
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 33
        }

        ComboBox {
            id: out_port
            x: 68
            y: 637
            width: 120
            height: 30
            anchors.bottomMargin: 33
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: 302
            anchors.bottom: parent.bottom
            model: api.midi_out
        }
    }
    Connections {
        target: api
    }
}

Tags: importselfrightapiiddefprocout
1条回答
网友
1楼 · 发布于 2024-05-17 02:34:45

您的代码有以下错误:

  • midi_out属性只能读取和通知,因为您无法写入(创建)midi设备,所以不要实现setter。

  • midi设备的名称仅在开始时获得。如果连接了其他设备呢?我将不得不关闭并重新打开应用程序,而是添加了允许更新设备名称的“reload()”函数。

  • 如果根元素是Window或ApplicationWindow,则必须使用QQmlApplicationEngine,如果是Item,则必须使用QQuickView。

  • 如果要将PySide2中的列表导出为属性,则必须使用QVariantList(1)

import multiprocessing as mp

import mido

from Fuzzy.aidrummer import AiDrummer

from PySide2.QtWidgets import QApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QUrl, Slot, QObject, Property, Signal


def run():
    d = AiDrummer(
        "playback",
        file="../Music/28 coltrane 2.mid",
        play_instrument="yes",
        instrument_port="VirtualMIDISynth #1 0",
        out_port="strike 3",
        visualize=True,
    )
    d.run()


class Api(QObject):
    midi_in_names_Changed = Signal()
    midi_out_names_Changed = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)

        self.proc = None
        self.reload()

    @Slot()
    def reload(self):
        self._midi_in_names = mido.get_input_names()
        self._midi_out_names = mido.get_output_names()
        self.midi_in_names_Changed.emit()
        self.midi_out_names_Changed.emit()

    def get_midi_in_names(self):
        return self._midi_in_names

    def get_midi_out_names(self):
        return self._midi_out_names

    midi_in_names = Property(
        "QVariantList", fget=get_midi_in_names, notify=midi_in_names_Changed
    )
    midi_out_names = Property(
        "QVariantList", fget=get_midi_out_names, notify=midi_out_names_Changed
    )

    @Slot()
    def play(self):
        self.proc = mp.Process(target=run)
        self.proc.start()

    @Slot()
    def stop(self):
        self.proc.kill()


if __name__ == "__main__":
    import os
    import sys

    app = QApplication(sys.argv)

    api = Api()

    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty("api", api)

    current_dir = os.path.dirname(os.path.realpath(__file__))

    url = QUrl.fromLocalFile(os.path.join(current_dir, "main.qml"))

    engine.load(url)

    if not engine.rootObjects():
        sys.exit(-1)

    sys.exit(app.exec_())
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.13
import QtQuick.Controls.Material 2.0

Window {
    id: window
    visible: true
    width: 980
    height: 700
    title: qsTr("AI Drummer")

    Rectangle {
        id: rectangle1
        color: "#191919"
        anchors.rightMargin: 0
        anchors.bottomMargin: 0
        anchors.leftMargin: 0
        anchors.topMargin: 0
        anchors.fill: parent
        clip: true
        rotation: 0

        Rectangle {
            id: rectangle
            x: 711
            width: 400
            height: 200
            color: "#3a3a3a"
            anchors.top: parent.top
            anchors.topMargin: -33
            anchors.right: parent.right
            anchors.rightMargin: -131
            rotation: 45
            clip: true
            Material.theme: Material.Dark
            Material.accent: Material.DeepOrange
        }

        RoundButton {
            id: playButton
            x: 356
            y: 632
            width: 100
            text: "Play"
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 28
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: 70
            onClicked: { api.play()}
        }

        RoundButton {
            id: stopButton
            x: 462
            y: 632
            width: 100
            text: "Stop"
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 28
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: -70
            onClicked: { api.stop()}
        }

        ComboBox {
            id: instrument_port
            x: 214
            y: 637
            width: 120
            height: 30
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: 176
            anchors.bottom: parent.bottom
            anchors.bottomMargin: 33
        }

        ComboBox {
            id: out_port
            x: 68
            y: 637
            width: 120
            height: 30
            anchors.bottomMargin: 33
            anchors.right: parent.horizontalCenter
            anchors.rightMargin: 302
            anchors.bottom: parent.bottom
            model: api.midi_out_names
        }
    }
}

(1)Registering a Python list property to QML in pyside2

相关问题 更多 >