如何在我的程序中添加 PyQt 菜单栏?

Posted

技术标签:

【中文标题】如何在我的程序中添加 PyQt 菜单栏?【英文标题】:How do I add a PyQt menubar to my program? 【发布时间】:2019-11-10 11:10:48 【问题描述】:

我目前正在使用 PyQt5 为我的 Python 程序开发用户界面。

在我的程序中,我首先读取了一个 csv 文件,然后使用 pandas 创建了一个数据框。到目前为止,这也有效。

现在我想用 PyQt5 创建一个用户界面。这个界面应该包含一个带有两个按钮(“文件”和“运行”)的菜单栏,并且应该显示我的数据框(见图)

它最终应该是什么样子

第一个按钮我想读取我的 csv 文件,另一个我想启动程序。

目前我只能用我的用户界面显示一个数据框(见图)

现在的样子

这是我目前的代码,带有随机数据框

import sys
import pandas as pd
from PyQt5.QtWidgets import QApplication, QTableView
from PyQt5.QtCore import QAbstractTableModel, Qt

df = pd.DataFrame('A': ['AAAAAAAA11111111', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'],
                   'B': ['BBBBBBBB11111111', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'],
                   'C': ['CCCCCCCC11111111', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'],        
                   'D': ['CCCCCCCC11111111', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz', 'xyz'])

class pandasModel(QAbstractTableModel):

    def __init__(self, data):
        QAbstractTableModel.__init__(self)
        self._data = data

    def rowCount(self, parent=None):
        return self._data.shape[0]

    def columnCount(self, parent=None):
        return self._data.shape[1]

    def data(self, index, role=Qt.DisplayRole):
        if index.isValid():
            if role == Qt.DisplayRole:
                return str(self._data.iloc[index.row(), index.column()])
        return None

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self._data.columns[col]
        return None

if __name__ == '__main__':
    app = QApplication(sys.argv)
    model = pandasModel(df)
    view = QTableView()
    view.setModel(model)
    view.resize(800, 300)
    view.horizontalHeader().setSectionResizeMode(1) 
    view.show()
    sys.exit(app.exec_())

为了维护我想要的用户界面,我创建了一个带有菜单栏的 PyQt Designer 界面(见图)。但我不知道如何链接这两个接口。

来自 PyQt_Designer 的设计

来自 PyQt 设计器的代码:

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(600, 300)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("../../Desktop/index.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)

        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(0, 0, 600, 300))
        self.tableWidget.viewport().setProperty("cursor", QtGui.QCursor(QtCore.Qt.CrossCursor))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(0)
        self.tableWidget.setRowCount(0)

        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 600, 21))
        self.menubar.setObjectName("menubar")
        self.menuSelect = QtWidgets.QMenu(self.menubar)
        self.menuSelect.setObjectName("menuSelect")

        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menuSelect.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Analyser"))
        self.menuSelect.setTitle(_translate("MainWindow", "Select 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_())

如何向我的程序添加菜单栏,或者如何将我的程序链接到 PyQt 设计器的代码?

【问题讨论】:

【参考方案1】:

首先,阅读PyQt documentation about using Designer。 长话短说,您应该从不编辑 pyuic 生成的 python 文件,而是创建您的代码并将生成的文件用作模块。阅读文档,您就会明白(您可能需要查看第三个示例)。

删除你添加的QTableWidget(因为它是错误的小部件类型),将QTableView拖到主窗口,设置布局(右键单击表格外和窗口内的空白处,并在“布局”子菜单中选择水平或垂直之一),保存并重建 UI 文件。

此时,按照文档中的过程,您只需从您的班级__init__ 中设置模型:

from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtCore import QAbstractTableModel, Qt
from ui_mainwindow import Ui_MainWindow

class pandasModel(QAbstractTableModel):
    # ...

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.model = pandasModel(df)
        self.tableView.setModel(self.model)

        self.actionOpen.triggered.connect(self.doSomething)

【讨论】:

@musicamate 非常感谢您的帮助。我试图实施您的建议,但收到以下错误消息。 ModuleNotFoundError:没有名为“ui_mainwindow”的模块 模块名是你从pyuic的新输出中保存的python文件名(不带扩展名),它必须在你的程序的同一路径中。如果您使用pyuic -o mymainwindow.py mainwindow.ui,那么您将使用from mymainwindow import Ui_MainWindow

以上是关于如何在我的程序中添加 PyQt 菜单栏?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QMainWindow 中创建菜单栏

如何将我的程序添加到 OS X 系统菜单栏?

在PyQt中构建 Python 菜单栏菜单和工具栏

如何在Android Studio的菜单应用程序标题栏中的项目之间添加行?

使用 C++ 在我的应用程序的菜单栏中创建“保存当前设置”功能

pyqt如何使应用程序真正活跃