我注意到 QML 可以使用 Connections 对象接收从 Python 发出的信号。不幸的是,我无法弄清楚如何让该对象接收该信号的参数。
我创建了一个最小的测试用例来演示我想要做什么:
最小.py
from PySide import QtCore, QtGui, QtDeclarative
import sys
# init Qt
app = QtGui.QApplication(sys.argv)
# set up the signal
class Signaller(QtCore.QObject):
emitted = QtCore.Signal(str)
signaller = Signaller()
# Load the QML
qt_view = QtDeclarative.QDeclarativeView()
context = qt_view.rootContext()
context.setContextProperty('signaller', signaller)
qt_view.setResizeMode(QtDeclarative.QDeclarativeView.SizeRootObjectToView)
qt_view.setSource('min.qml')
qt_view.show()
# launch the signal
signaller.emitted.emit("Please display THIS text!")
# Run!
app.exec_()
Run Code Online (Sandbox Code Playgroud)
和 min.qml
import QtQuick 1.0
Rectangle {
width:300; height:100
Text {
id: display
text: "No signal yet detected!" …Run Code Online (Sandbox Code Playgroud) 我想在Ubuntu上编写一个简单的桌面应用程序,我认为一种简单的方法是将Qt与QML用作GUI,将Python用作逻辑语言,因为我对Python有点熟悉。
现在,我花了几个小时尝试以某种方式连接GUI和逻辑,但是它不起作用。我管理连接QML-> Python,但没有其他方法。我有代表我的数据模型的Python类,并添加了JSON编码和解码功能。因此,目前尚不涉及SQL数据库。但是,也许QML视图和某些数据库之间的直接连接会使事情变得更容易?
所以现在一些代码。
QML-> Python
QML文件:
ApplicationWindow {
// main window
id: mainWindow
title: qsTr("Test")
width: 640
height: 480
signal tmsPrint(string text)
Page {
id: mainView
ColumnLayout {
id: mainLayout
Button {
text: qsTr("Say Hello!")
onClicked: tmsPrint("Hello!")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有我的slot.py:
from PySide2.QtCore import Slot
def connect_slots(win):
win.tmsPrint.connect(say_hello)
@Slot(str)
def say_hello(text):
print(text)
Run Code Online (Sandbox Code Playgroud)
最后是我的main.py:
import sys
from controller.slots import connect_slots
from PySide2.QtWidgets import QApplication
from PySide2.QtQml import QQmlApplicationEngine
if __name__ == '__main__':
app = QApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load('view/main.qml') …Run Code Online (Sandbox Code Playgroud) 我在 QtDesigner 中设计了一个基本的 UI。现在我试图通过单击按钮弹出一个简单的文件对话框,下面给出的是我的 GUI 代码:
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
.....
.....
self.input_Image_GraphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.input_Image_GraphicsView.setGeometry(QtCore.QRect(730, 110, 480, 320))
self.input_Image_GraphicsView.setObjectName("input_Image_GraphicsView")
......
self.output_Image_GraphicsView = QtWidgets.QGraphicsView(self.centralwidget)
self.output_Image_GraphicsView.setGeometry(QtCore.QRect(730, 480, 480, 320))
self.output_Image_GraphicsView.setObjectName("output_Image_GraphicsView")
......
self.file_Select_Btn = QtWidgets.QPushButton(self.centralwidget)
self.file_Select_Btn.setGeometry(QtCore.QRect(1082, 80, 121, 28))
self.file_Select_Btn.setObjectName("file_Select_Btn")
self.file_Select_Btn.clicked.connect(self.selectFile)
.....
.....
def selectFile():
self.path_To_File = QtWidgets.QFileDialog.getOpenFileName(self, QtCore.QObject.tr("Load Image"), QtCore.QObject.tr("~/Desktop/"), QtCore.QObject.tr("Images (*.jpg)"))
print(self.path_To_File)
.....
.....
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误: …
在构建我的 PySide2 项目时发生 Qt 错误,但我已经在我的系统中安装了 Qt。
我尝试在 Windows 中构建项目,结果很好,给它一个 Dll 错误——因为我的项目使用了一个——;但代码本身在 Windows 或 Linux 中运行得很好。
...
22440 INFO: Loading module hooks...
22440 INFO: Loading module hook "hook-httplib2.py"...
22441 INFO: Loading module hook "hook-PySide2.QtGui.py"...
22550 WARNING: Cannot read QLibraryInfo output: raised Expecting value: line 1 column 1 (char 0) when decoding:
False
22550 INFO: Loading module hook "hook-PySide2.QtWidgets.py"...
22551 INFO: Loading module hook "hook-pydoc.py"...
22552 INFO: Loading module hook "hook-distutils.py"...
22554 INFO: Loading module hook "hook-pkg_resources.py"...
22555 INFO: Loading module hook …Run Code Online (Sandbox Code Playgroud) 我想在 MacOS 上使用 Python3.7
我已经是 Python 2.7 版本了。
我在 上创建了一个别名.bash_profile,alias python="/usr/local/bin/python3.7"然后source ~/.bash_profile。
所以我删除了 Python2.7 /usr/local/lib/
现在,当我尝试执行时pip install PySide2,出现错误:
Traceback (most recent call last):
File "/usr/local/bin/pip", line 6, in <module>
from pkg_resources import load_entry_point
ImportError: No module named pkg_resources
Run Code Online (Sandbox Code Playgroud)
我认为自从我删除 Python2.7 后就发生了这个错误
有人可以帮助我解决我的错误吗?
谢谢 !
我试图在我的 PySide2 应用程序中打开一个文件,但文件对话框总是在主窗口下方打开,并在启动器中显示为另一个应用程序。应用程序的名称是“门户”。
我看到其他答案,其中解决方案是将主窗口作为第一个参数传递给getOpenFileName(),但这对我不起作用。
这是问题的简单演示:
import sys
from PySide2.QtWidgets import QPushButton, QFileDialog, QApplication
class DemoButton(QPushButton):
def __init__(self, text):
super().__init__(text)
self.clicked.connect(self.on_click)
def on_click(self):
file_name, _ = QFileDialog.getOpenFileName(
self,
"Open a text file.",
filter='Text file (*.txt)')
print(file_name)
def main():
app = QApplication(sys.argv)
button = DemoButton("Hello World")
button.show()
app.exec_()
sys.exit()
main()
Run Code Online (Sandbox Code Playgroud)
我想也许父母必须是一个QMainWindow,所以我试过:
import sys
from PySide2 import QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
main_widget = QtWidgets.QWidget(self)
self.setCentralWidget(main_widget)
# layout initialize
g_layout = QtWidgets.QVBoxLayout()
layout = …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
if __name__ == '__main__':
os.environ["QT_QUICK_CONTROLS_STYLE"] = "Material"
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
engine.load('./QML/main.qml')
if not engine.rootObjects():
sys.exit(-1)
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,如果“engine.load”失败,我只会看到“-1”退出代码,而不会详细说明失败的原因以及发生的错误。如何在 python 控制台中打印 QML 错误?
QQuickView当使用而不是 QQmlApplicationEngine时,有一个解决方法,并在这篇文章中进行了描述,但是,我想知道 QQmlApplicationEngine 是否可以实现类似的功能?
我想发送字典,其中包含动态创建 qml 对象所需的数据,从 PySide2 类发送到 QML 接口,并且由于我需要响应某些事件来执行此操作,因此我需要使用信号和槽。
由于我刚刚开始使用 QML 和 python,我尝试创建一个简单的项目只是为了玩玩(正如您从代码中看到的)
质量管理语言:
import QtQuick 2.10
import QtQuick.Controls 2.2
import QtQuick.Window 2.2
import QtQuick.Controls.Material 2.3
import QtQuick.Layouts 1.0
ApplicationWindow {
id: mainWindow
width:640
height: 480
title: qsTr("Simple ui")
visible: true
locale:locale
Rectangle {
id: appWindow
objectName: "splasso"
anchors.fill: parent
color: "yellow"
Material.accent: Material.DeepPurple
Material.primary: Material.Cyan
Component.onCompleted: function(){
TestVar.theSignal.connect(catchAnswer);
testList.append(stuff1);
testList.append(stuff2);
testList.append(stuff3);
testCombo.currentIndex = 0;
//Just a pointless test print
console.log(JSON.stringify(stuff1));
}
function catchAnswer(answer){
console.log(JSON.stringify(answer));
}
ComboBox{
id: testCombo
anchors.centerIn: parent
width: …Run Code Online (Sandbox Code Playgroud) 我有一个在 python3.6 下运行的 python 应用程序,并使用 PyQt5 加载 Ui 窗口。这些窗口是使用 Qt Designer 5.9.4 创建的。下面的代码显示了 PyQt5 的工作示例。
现在我想拥有完全相同的功能,但使用 PySide2。目前,我无法弄清楚如何加载 Ui 文件并在单独的类中使用其对象(按钮、表格等)。例如:通过单击第一个窗口/类中的按钮,会出现第二个窗口,其中的函数是在单独的类中定义的,请参阅示例。我找到的所有示例都只是加载一个 Ui 窗口,但没有展示如何使用它。有人可以帮忙吗?
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from PyQt5.uic import loadUiType
from PyQt5 import QtGui, QtCore
Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')
class First(Ui_FirstWindow, QFirstWindow):
def __init__(self):
super(First, self).__init__()
self.setupUi(self)
self.button.clicked.connect(self.show_second_window)
def show_second_window(self):
self.Second = Second()
self.Second.show()
class Second(Ui_SecondWindow, QSecondWindow):
def __init__(self):
super(Second, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud) 由于以下代码,我从 PyQt5 切换到 PySide2 时遇到一些问题:
class EnumModel(QtCore.QAbstractListModel):
def __init__(self, list_of_enums):
"""
Enumeration model
:param list_of_enums: list of enumeration values to show
"""
QtCore.QAbstractListModel.__init__(self)
self.items = list_of_enums
def rowCount(self, parent=QtCore.QModelIndex()):
return len(self.items)
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid() is True:
if role == QtCore.Qt.DisplayRole:
return QtCore.QVariant(self.items[index.row()].value[0])
elif role == QtCore.Qt.ItemDataRole:
return QtCore.QVariant(self.items[index.row()].value[0])
return QtCore.QVariant()
Run Code Online (Sandbox Code Playgroud)
代码在 PyQt5 下运行良好。
在我的迁移过程中我发现官方网站说:
PySide 仅支持 PyQt 的 API 2(请参阅 PSEP 101)了解详细信息。因此 Qt 类(例如 QStrings、QStringLists 和 QVariants)在 PySide 上不可用。相反,您应该简单地使用本机 Python 数据类型。
所以解决方案是(我猜)简单地更改QVariant为str …
pyside2 ×10
python ×8
qml ×4
python-3.x ×3
pyqt5 ×2
filedialog ×1
linux ×1
pip ×1
pyinstaller ×1
pyside ×1
python-2.7 ×1
qt ×1
qt-designer ×1
qt-signals ×1
qt-slot ×1