gpt4 book ai didi

python - PyQt 启动时加载函数(qml 加载器)

转载 作者:行者123 更新时间:2023-12-01 09:29:05 25 4
gpt4 key购买 nike

您好,我有以下问题:

这是我的工作代码

import sys
from PyQt5.QtCore import QObject, QUrl, Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
import os
import vlc
from time import sleep

# define VLC instance
instance = vlc.Instance()

# Define VLC player
instance = vlc.Instance('--input-repeat=-1', '--fullscreen')

player = instance.media_player_new()


list_test = []
list_name = []


def prepare_url(url):

media = instance.media_new(url)
player.set_media(media)


if __name__ == "__main__":
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QApplication(sys.argv)

engine = QQmlApplicationEngine()
ctx = engine.rootContext()
ctx.setContextProperty("main", engine)
engine.load('SimpleQML.qml')

win = engine.rootObjects()[0]
win.show()
button = win.findChild(QObject, "playBtn")


def myFunction():
print("A fine piece of text")



button.clicked.connect(myFunction) # works on click
myFunction() #works with out clicking

sys.exit(app.exec_())

现在我想通过执行以下代码来扩展它:

import sys
from PyQt5.QtCore import QObject, QUrl, Qt
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine
import os
import vlc
from time import sleep

# define VLC instance
instance = vlc.Instance()

# Define VLC player
instance = vlc.Instance('--input-repeat=-1', '--fullscreen')

player = instance.media_player_new()


list_test = []
list_name = []


def prepare_url(url):

media = instance.media_new(url)

player.set_media(media)


if __name__ == "__main__":
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QApplication(sys.argv)

engine = QQmlApplicationEngine()
ctx = engine.rootContext()
ctx.setContextProperty("main", engine)
engine.load('SimpleQML.qml')

win = engine.rootObjects()[0]
win.show()
button = win.findChild(QObject, "playBtn")
comboBox = win.findChild(QObject, "comboBox")

def myFunction():
print("das")

def list_fill():
with open("config/stations.txt") as f:
content = f.readlines()
content = [x.strip() for x in content]
list_t = [item.split("|")[0] for item in content if item]
list_n = [item.split("|")[1] for item in content if item]
del list_test[:]
del list_name[:]
comboBox.clear()
for x in list_t:
list_test.append(x)
for x in list_n:
list_name.append(x)

addItems(list_name)

button.clicked.connect(myFunction) # works too
myFunction()
list_fill() #calling this crashes program
sys.exit(app.exec_())

最后这是错误

    das
Traceback (most recent call last):
File "/home/flea/Desktop/quick qt/main.py", line 65, in <module>
list_fill()
File "/home/flea/Desktop/quick qt/main.py", line 55, in list_fill
comboBox.clear()
AttributeError: 'QObject' object has no attribute 'clear'

我尝试使用硬编码列表进行 ti 操作,但列表不是问题,由于某种原因,python 无法识别我的组合框。我不确定这里的问题是什么。我可以加载我的按钮并向其添加单击事件(有效),但我无法将列表添加到我的组合框。

这是我的 Qml

 import QtQuick 2.10
import QtQuick.Controls 2.1
import QtQuick.Window 2.2
import QtQuick.Controls.Material 2.3



ApplicationWindow {
id: applicationWindow
Material.theme: Material.Light
title: qsTr("Test Invoke")

width: 600
height: 500

Row {
id: row
width: 200
height: 400
anchors.left: parent.left
anchors.leftMargin: 5
anchors.top: parent.top
anchors.topMargin: 5

Button{
id: playBtn


objectName: "playBtn"
text : "Play"
checked: false
padding: 6
rightPadding: 8
font.wordSpacing: 0
font.pointSize: 10
font.family: "Times New Roman"
topPadding: 4
highlighted: true
Material.accent: Material.Red



}

Button {
id: stopBtn
objectName: "stopBtn"
text: qsTr("Stop")
anchors.left: playBtn.right
anchors.leftMargin: 5
}

Button {
id: stfBtn
text: qsTr("Save")
objectName: "stfBtn"
anchors.left: stopBtn.right
anchors.leftMargin: 5
}

Button {
id: minimize
objectName: "minBtn"
text: qsTr("Min")
anchors.left: stfBtn.right
anchors.leftMargin: 5
}
}

Column {
id: column
x: 135
y: 100
width: 200
height: 400

TextField {
objectName: "nameText"
id: nameText
width: 300
text: qsTr("")
}

TextField {
objectName: "urlText"
id: urlText
width: 300
text: qsTr("")
}

ComboBox {
objectName: "comboBox"
id: comboBox
width: 200
}
}

Slider {
id: slide
objectName: "slider"
x: 160
y: 311
value: 0.5
}




}

最佳答案

随着时间的推移,实例化从 Python 或 C++ 在 QML 中创建的对象既不好,也不可维护。

适当的做法是用 Python 或 C++ 创建一个对象并将其发送到 QML,然后创建允许与 QML 交互的 qproperties 和槽。

在你的情况下,我猜list_fill会尝试将数据添加到ComboBox,但是ComboBox没有明确的方法,所以如果你想清理它,只需向它传递一个空列表,或者在你的情况下传递它新列表。

另一方面,调用show()并不优雅,最好将ApplicationWindow的visible属性设置为true。

ma​​in.py

import sys
import os

from PyQt5.QtCore import QObject, QUrl, Qt, pyqtSlot, pyqtSignal, pyqtProperty
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQml import QQmlApplicationEngine

import vlc

# define VLC instance
instance = vlc.Instance()

# Define VLC player
instance = vlc.Instance('--input-repeat=-1', '--fullscreen')

player = instance.media_player_new()


list_test = []
list_name = []

def prepare_url(url):
media = instance.media_new(url)
player.set_media(media)

class Manager(QObject):
stationsChanged = pyqtSignal()
currentStationChanged = pyqtSignal()
def __init__(self):
QObject.__init__(self)
self.m_stations = []
self.m_currentStation = ""
self.currentStationChanged.connect(self.on_currentStationChanged)

@pyqtProperty(str, notify=currentStationChanged)
def currentStation(self):
return self.m_currentStation

@currentStation.setter
def currentStation(self, val):
if self.m_currentStation == val:
return
self.m_currentStation = val
self.currentStationChanged.emit()

@pyqtProperty(list, notify=stationsChanged)
def stations(self):
return self.m_stations

@stations.setter
def stations(self, val):
if self.m_stations == val:
return
self.m_stations = val[:]
self.stationsChanged.emit()

@pyqtSlot()
def play(self):
print("play", self.currentStation)

@pyqtSlot()
def stop(self):
print("stop")

@pyqtSlot()
def on_currentStationChanged(self):
print(self.currentStation)

def list_fill(self):
l = []
with open("config/stations.txt") as f:
content = f.readlines()
content = [x.strip() for x in content]
list_t = [item.split("|")[0] for item in content if item]
list_n = [item.split("|")[1] for item in content if item]
l += list_t + list_n
self.stations = l



if __name__ == "__main__":
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QApplication(sys.argv)

engine = QQmlApplicationEngine()
manager = Manager()
ctx = engine.rootContext()
ctx.setContextProperty("Manager", manager)
engine.load('main.qml')
if not engine.rootObjects():
sys.exit(-1)
manager.list_fill()
sys.exit(app.exec_())

ma​​in.qml

import QtQuick 2.10
import QtQuick.Controls 2.1
import QtQuick.Window 2.2
import QtQuick.Controls.Material 2.3

ApplicationWindow {
id: applicationWindow
Material.theme: Material.Light
title: qsTr("Test Invoke")
visible: true

width: 600
height: 500

Row {
id: row
width: 200
height: 400
anchors.left: parent.left
anchors.leftMargin: 5
anchors.top: parent.top
anchors.topMargin: 5

Button{
id: playBtn
text : "Play"
checked: false
padding: 6
rightPadding: 8
font.wordSpacing: 0
font.pointSize: 10
font.family: "Times New Roman"
topPadding: 4
highlighted: true
Material.accent: Material.Red
onClicked: Manager.play()
}

Button {
id: stopBtn
text: qsTr("Stop")
anchors.left: playBtn.right
anchors.leftMargin: 5
onClicked: Manager.stop()
}

Button {
id: stfBtn
text: qsTr("Save")
objectName: "stfBtn"
anchors.left: stopBtn.right
anchors.leftMargin: 5
}

Button {
id: minimize
objectName: "minBtn"
text: qsTr("Min")
anchors.left: stfBtn.right
anchors.leftMargin: 5
}
}

Column {
id: column
x: 135
y: 100
width: 200
height: 400

TextField {
id: nameText
width: 300
text: qsTr("")
}

TextField {
id: urlText
width: 300
text: qsTr("")
}

ComboBox {
id: comboBox
width: 200
model: Manager.stations
onCurrentTextChanged: Manager.currentStation = currentText
}
}

Slider {
id: slider
x: 160
y: 311
value: 0.5
}
}

这种实现的优点是可以独立修改设计和逻辑部分。如果您通过 setContextProperty 传递一个对象,它将在所有 .qml 文件中可见。使用之前的方法,如果您有很多 .qml,就会遇到问题

关于python - PyQt 启动时加载函数(qml 加载器),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50118684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com