标签: pyside2

Shiboken2和自定义Qt小部件

在Windows上,我需要在Python中使用一些用C++编写的自定义Qt5小部件,pyside2因为它的许可证我必须使用它.

我已经能够pyside2从源代码编译库(连同shiboken2示例),但我无法找到如何包装自定义Qt5小部件的简单示例.

我知道pyside2仍然没有正式发布,但它似乎已经被使用(例如,在Maya中):在PySide2应用程序中,我如何获得QWindow的ID?

任何人都可以给出提示或指示吗?一个最小的例子会更好.


编辑

根据@placinta评论,我创建了一个包含一个最小示例的repo,它试图包装一个自定义QMainWindow.

在我的测试中,我使用了包装5.6 的pyside2 Conda包Qt.

当我执行shiboken2可执行文件时,我收到了大量的警告.

我认为这些警告触发编译错误shiboken2生成的代码.

c++ windows python-3.x qt5 pyside2

5
推荐指数
1
解决办法
952
查看次数

PySide2和pyinstaller gui应用程序无法在某些Windows计算机上运行

我使用PySide2作为我的GUI框架和PyInstaller构建了一个小的gui应用程序,以制作一个文件exe文件。

该应用程序可以在某些PC(Windows 7和10)上完美运行,但是在其他PC上则无法启动-向我显示错误消息:

“致命错误!:无法执行脚本pyi_rth_qt5plugins”

我相信它可能不会捆绑Qt5Gui.dll,Qt5Core.dll和Qt5Widgets.dll,但是我不知道如何使用PyInstaller做到这一点。

有谁知道如何解决这个问题?

这是我的.spec文件:

# -*- mode: python -*-

block_cipher = None

a = Analysis(['main.py'],
             pathex=[],
             binaries=[],
             datas=[],
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='Application',
          debug=True,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True , icon='Images\\Application_icon.ico')
Run Code Online (Sandbox Code Playgroud)

编辑

这是从cmd运行且debug = True时的完整输出。我发现奇怪的是,它是指我在(例如File "c:\users\jake\Projects\Application\venv\lib\site-packages\PyInsta ller\loader\pyimod03_importers.py", line 714, in load_module)上开发应用程序的PC,而不是我正在测试并从中获得此错误消息的PC。

[4588] PyInstaller Bootloader 3.x
[4588] LOADER: executable is C:\Users\User\Desktop\Application.exe
[4588] LOADER: homepath is C:\Users\User\Desktop
[4588] LOADER: _MEIPASS2 is NULL
[4588] …
Run Code Online (Sandbox Code Playgroud)

qt pyinstaller pyside python-3.x pyside2

5
推荐指数
0
解决办法
2085
查看次数

PySide 如何在 python 控制台中查看 QML 错误?

我有以下代码:

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 是否可以实现类似的功能?

python qml pyside2

5
推荐指数
1
解决办法
2036
查看次数

如何使用 Signal 将 python 字典发送到 QML 接口?

我想发送字典,其中包含动态创建 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)

python qml qt-signals qt-slot pyside2

5
推荐指数
1
解决办法
2099
查看次数

PyQt5 到 PySide2,加载不同类中的 UI 文件

我有一个在 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)

python qt-designer pyqt5 pyside2

5
推荐指数
1
解决办法
5332
查看次数

从 PyQt5 迁移到 PySide2 时的 QVariant 替代方案

由于以下代码,我从 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 数据类型。

所以解决方案是(我猜)简单地更改QVariantstr …

python pyqt5 pyside2

5
推荐指数
1
解决办法
5921
查看次数

使用 PyInstaller 后,FigureCanvas 未解释为 QtWidget

我对 matplotlib 中的示例进行了轻微修改:https://matplotlib.org/gallery/user_interfaces/embedding_in_qt_sgskip.html

唯一改变的是导入,因为我使用的是 PySide2,所以导入看起来像这样:

from PySide2 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
Run Code Online (Sandbox Code Playgroud)

在 pycharm 中运行代码或单独运行脚本时,这工作正常,但是在使用 PyInstaller 创建 .exe 后,我收到以下错误:

TypeError: 'PySide2.QtWidgets.QBoxLayout.addWidget' called with wrong argument types:                                     
  PySide2.QtWidgets.QBoxLayout.addWidget(FigureCanvasQTAgg)                                                            
Supported signatures:                                                                                                     
  PySide2.QtWidgets.QBoxLayout.addWidget(PySide2.QtWidgets.QWidget, int=0, 
  PySide2.QtCore.Qt.Alignment=Default(Qt.Alignment))                                                                                                                     
  PySide2.QtWidgets.QBoxLayout.addWidget(PySide2.QtWidgets.QWidget)
Run Code Online (Sandbox Code Playgroud)

看来FigureCanvasQtAgg不再被识别为QWidget,因此无法将其添加到布局中。

我尝试添加这些行来建议 pyside,如下所示

os.environ["QT_API"] = "PySide2"
matplotlib.use('Qt5Agg')
matplotlib.rcParams['backend.qt5']='PySide2'
Run Code Online (Sandbox Code Playgroud)

但是,这不会更改 exe 的错误消息。在pycharm中仍然运行良好。

编辑:替换此行后,这似乎是 PySide2+PyInstaller 的一些问题:

from PySide2 import QtCore, QtWidgets
Run Code Online (Sandbox Code Playgroud)

用这一行:

from PyQt5 import QtCore, QtWidgets
Run Code Online (Sandbox Code Playgroud)

即使在使用 PyInstaller 之后它仍然可以工作。

但我想使用 PySide2 而不是 PyQt5,有人知道解决这个问题的方法吗?

python matplotlib pyside2

5
推荐指数
1
解决办法
2138
查看次数

如何在 PySide2 中将 python 列表转换为 QVariantList

因此,PySide2 删除了 QVariant* 类型。

然而,QtQuick 公开了大量的 QVariant API。

更具体地说,我想使用非常方便的功能将 QVariantList 作为 ListView 的模型传递,而不必实现完全成熟的 QAIM。

然而,通过 setContextProperty 将这样的对象提供给 QML

class Test(QObject):
   def __init__(self):

       super(Test, self).__init__()
       self.propertyList = ["FOO", "BAR", 1]

   def model(self):
       return self.propertyList

   modelChanged = Signal()
   model = Property(list, model, notify=modelChanged)
Run Code Online (Sandbox Code Playgroud)

然后打印 .model 产生:

qml: QVariant(PySide::PyObjectWrapper)
Run Code Online (Sandbox Code Playgroud)

那么如何以 qml 实际能够理解的形式将 python 列表传递给 qml 呢?

python qml pyside2

5
推荐指数
1
解决办法
2265
查看次数

PySide2 等效于 PyQt5 的 loadUiType() 以在 UI 设计中动态混合

TL;DR:我想要一个直接替换 PyQt5 的loadUiType()功能的uic模块,它可以与 PySide2 和 Python 3.6+ 一起使用。


我想将 PyQt5 应用程序迁移到 PySide2。我使用的一个常见模式是,我在 Qt Designer 中创建用户界面设计,并动态加载生成的.ui文件作为扩展 Python 代码中 Qt 小部件的混合类,例如主窗口本身:

from PyQt5 import QtWidgets, uic

class Window(QtWidgets.QMainWindow, uic.loadUiType('design.ui')[0]):

    def __init__(self):
        super().__init__()
        self.setupUi(self)
        print(self.label.text())

app = QtWidgets.QApplication([])
window = Window()
window.show()
app.exec_()
Run Code Online (Sandbox Code Playgroud)

这意味着我可以放弃在命令行上将.ui设计编译为.pyPython 模块。更重要的是,混合模式让我可以通过self.name导入窗口小部件的范围内访问设计中定义的所有 Qt 窗口小部件,name在 Qt 设计器中指定的位置。

为了提供可重现的示例,这里有一个与上述 Python 代码一起使用的最小 Qt 设计文件,其中引用为design.ui

from PyQt5 import QtWidgets, uic

class Window(QtWidgets.QMainWindow, uic.loadUiType('design.ui')[0]):

    def __init__(self):
        super().__init__()
        self.setupUi(self) …
Run Code Online (Sandbox Code Playgroud)

python qt-designer python-3.x pyqt5 pyside2

5
推荐指数
1
解决办法
1991
查看次数

鼠标移动事件上的鼠标位置设置在父级而不是子级上

我正在学习 python 和 PySide2 并跟进 learnpytq 的一些教程,特别是https://www.learnpyqt.com/courses/custom-widgets/bitmap-graphics/,我陷入了困境。

接下来,创建像素图画布后,我们在小部件上移动 mouseMoveEvent 以确保鼠标的坐标始终相对于画布。我已经复制了提供的源,但仍在运行的应用程序中,鼠标位置相对于窗口(或父窗口小部件,我不确定),导致绘制的线条偏移到鼠标位置。

这是代码:

import sys
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt

class Canvas(QtWidgets.QLabel):

    def __init__(self):
        super().__init__()
        pixmap = QtGui.QPixmap(600, 300)
        self.setPixmap(pixmap)

        self.last_x, self.last_y = None, None
        self.pen_color = QtGui.QColor('#000000')

    def set_pen_color(self, c):
        self.pen_color = QtGui.QColor(c)

    def mouseMoveEvent(self, e):
        if self.last_x is None: # First event.
            self.last_x = e.x()
            self.last_y = e.y()
            return # Ignore the first time.

        painter = QtGui.QPainter(self.pixmap())
        p = painter.pen()
        p.setWidth(4)
        p.setColor(self.pen_color)
        painter.setPen(p) …
Run Code Online (Sandbox Code Playgroud)

python pyside2

5
推荐指数
1
解决办法
1708
查看次数