PySide6 widgets not showing when using pyside6-uic

huangapple go评论67阅读模式
英文:

PySide6 widgets not showing when using pyside6-uic

问题

编辑:
评论指出格式错误的__init__,这是正确的。这部分修复了我的问题;如果我执行self.ui.buttonBox.accepted.connect(self.fn),则一切正常。然而,在我的先前解决方案中,所有小部件都是在没有self.ui的情况下访问的。我想我的真正问题是是否有一种简单的方法可以避免self.ui,而不必手动浏览每个小部件并移动引用?对于阅读此帖子并有相同抱怨的任何人来说,答案是执行以下操作:

ui = Ui_MainWindow()
ui.setupUi(self)
for field, value in ui.__dict__.items():
    setattr(self, field, value)

我正在处理一个使用pyqtgraph(PyQt6)的项目,但它没有我需要的某些方法,而PySide6却有,所以我正在迁移我的代码到PySide6。以前使用PyQt6,我只需执行以下操作:

from pyqtgraph.Qt import uic

# 稍后
def __init__(self):
    super().__init__()
    uic.loadUi('uifile.ui', self)

然后,我可以直接使用self.[小部件名称]访问Qt Designer中的任何小部件。当转到PySide6时,我遵循了文档的第1部分,做了这个(最小示例):

from ui_test import Ui_MainWindow
from PySide6 import QtWidgets
import pyqtgraph as pg
import sys

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.buttonBox.accepted.connect(self.fn)

    def fn(self):  
        pass
        
if __name__ == '__main__':
    app = pg.mkQApp()
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

我通过执行pyside6-uic "test.ui" > ui_test.py生成了Ui_MainWindow(),如文档中所示,这会生成以下代码:

# -*- coding: utf-8 -*-

###################################################################################
## Form generated from reading UI file 'test.ui'
##
## Created by: Qt User Interface Compiler version 6.5.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
###################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialogButtonBox, QHBoxLayout,
    QMainWindow, QMenuBar, QSizePolicy, QStatusBar,
    QWidget)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName("MainWindow")
        MainWindow.resize(640, 480)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout = QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.buttonBox = QDialogButtonBox(self.centralwidget)
        self.buttonBox.setObjectName("buttonBox")
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)

        self.horizontalLayout.addWidget(self.buttonBox)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName("menubar")
        self.menubar.setGeometry(QRect(0, 0, 640, 22))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", "MainWindow", None))
    # retranslateUi

但是,当我运行应用程序时,没有小部件出现,只有一个空的主窗口。我在这里做错了什么?我已经尝试将pyqtgraph.Qt导入替换为PySide6,但没有起作用。

英文:

EDIT:
Comment points out wrongly formatted __init__, which is true. This partially fixes my issue; if I do self.ui.buttonBox.accepted.connect(self.fn) then things work fine. However in my previous solution, all widgets were addressed without self.ui. I guess my real question is whether or not there is an easy way to avoid the self.ui without manually going through every widget and moving the reference? The answer, for anyone reading this with the same complaint, is to do this:

ui = Ui_MainWindow()
ui.setupUi(self)
for field, value in ui.__dict__.items():
    setattr(self, field, value)

I was working on a project with pyqtgraph (PyQt6) but it didn't have certain methods that I require that PySide6 does have, so I am working on migrating my code over to PySide6. Previously with PyQt6 I just did

from pyqtgraph.Qt import uic
#later 
def __init__(self):
    super().__init__()
    uic.loadUi('uifile.ui', self)

And that was that; I could directly address whatever widgets I had in Qt designer with self.[Widget name].When moving to PySide6, I followed the documentation in part 1 and did this (minimal example).

from ui_test import Ui_MainWindow
from pyqtgraph.Qt import QtWidgets
import pyqtgraph as pg
import sys

class MainWindow(QtWidgets.QMainWindow):
    def __init(self):
        super().__init__()
        self.ui =  Ui_MainWindow()
        self.ui.setupUi(self)
        self.buttonBox.accepted.connect(self.fn)
    def fn(self):  
        pass
        
if __name__ == '__main__':
    app = pg.mkQApp()
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

I generated the Ui_MainWindow() by doing pyside6-uic "test.ui"> ui_test.py as shown in the documentation, which generated this code:

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'test.ui'
##
## Created by: Qt User Interface Compiler version 6.5.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QAbstractButton, QApplication, QDialogButtonBox, QHBoxLayout,
    QMainWindow, QMenuBar, QSizePolicy, QStatusBar,
    QWidget)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        if not MainWindow.objectName():
            MainWindow.setObjectName(u"MainWindow")
        MainWindow.resize(640, 480)
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName(u"centralwidget")
        self.horizontalLayout = QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.buttonBox = QDialogButtonBox(self.centralwidget)
        self.buttonBox.setObjectName(u"buttonBox")
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok)

        self.horizontalLayout.addWidget(self.buttonBox)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName(u"menubar")
        self.menubar.setGeometry(QRect(0, 0, 640, 22))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName(u"statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)

        QMetaObject.connectSlotsByName(MainWindow)
    # setupUi

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
    # retranslateUi

But when I run the app, no widgets appear, and I just get an empty main window. What am I doing wrong here? I already tried replacing the pyqtgraph.Qt import with PySide6 but that didn't work.

答案1

得分: 1

我认为你的问题不是由PySide6引起的,而是由pyqtgraph引起的。
我记得我在创建我的代码时遇到了类似的问题,因为pygraph的示例是独立的,而我希望pyqtgraph图表成为我的现有Qt应用程序的一部分。

以下是对我有效的代码部分 - 我突出显示了与你的方法的主要区别。
我在代码中构建了ChartWindow,但是是的,你也可以从ui文件创建它,没有问题。区别在于 - 我使用了原生的PySide6类,并将pyqtgraph作为继承自pg.GraphicsLayoutWidget的小部件(然后我在此小部件的构造函数中添加了坐标轴和绘图区域)。

from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout
import pyqtgraph as pg

class ChartView(pg.GraphicsLayoutWidget):   <-- 这是从PG类创建的小部件
    def __init__(self):
        pg.setConfigOptions(foreground='#000', background='#fff')
        super().__init__()   
        # 然后此类创建坐标轴、绘图区域和所有其他PG内容
    ..........................


class ChartWindow(QMainWindow):      <--- 我从Qt原生类派生我的主窗口
    def __init__(self):
        QMainWindow.__init__(self)
        self.layout = QVBoxLayout()
        self.chart = ChartView()     <--- 并将PG窗口包含在我的布局中
        self.layout.addWidget(self.chart)
        self.chart.setMinimumSize(800, 600)
   ...................

def main():
    app = QApplication()             <--- 使用原生的Qt应用程序对象
    chart = ChartWindow()
    chart.show()
    return app.exec()


if __name__ == '__main__':
    main()
英文:

I think your problem is caused not by PySide6 but by pyqtgraph.
I remember that I faced similar problems creating my code because pygraph examples were standalone while I wanted pyqtgraph-charts to be part of my existing Qt application.

Below is a part of code that works for me - I highlighted main differences from your approach.
I built ChartWindow in code but yes, you may create it from ui-file, not problem with it. The difference is - I used native PySide6 classes and included pyqtgraph as a widget derived from pg.GraphicsLayoutWidget (then I added axes and plot area in a constructor of this widget).

from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout
import pyqtgraph as pg
class ChartView(pg.GraphicsLayoutWidget):   <-- this is a widget created from PG class 
def __init__(self):
pg.setConfigOptions(foreground='#000', background='#fff')
super().__init__()   
# This class then creates axes, plot area and all other PG stuff
..........................
class ChartWindow(QMainWindow):      <--- I derive my Main window from Qt native class
def __init__(self):
QMainWindow.__init__(self)
self.layout = QVBoxLayout()
self.chart = ChartView()     <--- and include PG window in my layout
self.layout.addWidget(self.chart)
self.chart.setMinimumSize(800, 600)
...................
def main():
app = QApplication()             <--- Native Qt application object is used
chart = ChartWindow()
chart.show()
return app.exec()
if __name__ == '__main__':
main()    

huangapple
  • 本文由 发表于 2023年6月29日 05:18:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/76576763.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定