【问题标题】:PyQt - Action Only Producing Last ValuePyQt - 只采取行动产生最后的价值
【发布时间】:2017-08-28 14:09:03
【问题描述】:

以下是我的部分分析 GUI 代码。当单击菜单中的一个国家/地区时,应生成与该国家/地区不同的菜单。然而,此刻,无论按下哪个国家,最后一个国家都将是生成菜单的那个国家(在这种情况下,单击任一国家都会生成荷兰的菜单)。这是为什么呢?

import csv
import math
import itertools
import numpy as np
from PyQt4 import QtCore, QtGui
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(QtGui.QMainWindow):

    def countryAction(self):

        window = QtGui.QMainWindow(self)
        window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        window.setWindowTitle(self.tr(country))
        window.show()

    def setupUi(self, MainWindow):
        MainWindow.setGeometry(50, 50, 500, 300)
        MainWindow.setWindowTitle('uAnalytics')
        MainWindow.setWindowIcon(QtGui.QIcon('uTalkLogo.png'))

        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 867, 22))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuCountry = QtGui.QMenu(self.menubar)
        self.menuCountry.setObjectName(_fromUtf8("menuCountry"))
        self.menuPopular_Countries = QtGui.QMenu(self.menuCountry)
        self.menuPopular_Countries.setObjectName(_fromUtf8("menuPopular_Countries"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.actionAll_Countries = QtGui.QAction(MainWindow)
        self.actionAll_Countries.setObjectName(_fromUtf8("actionAll_Countries"))
        self.menuCountry.addAction(self.actionAll_Countries)
        self.menuCountry.addSeparator()
        self.menuCountry.addAction(self.menuPopular_Countries.menuAction())

        continents = {}
        countries = {}
        popularcountries = ['United States', 'United Kingdom', 'South Africa', 'Germany', 'India', 'Australia', 'Canada', 'Italy', 'Sweden' ,\
    'Netherlands', 'France', 'New Zealand', 'Belgium', 'Switzerland', 'Norway', 'Brazil', 'Indonesia', 'Russia', \
    'United Arab Emirates', 'Spain', 'Denmark']
        DIR = '/Users/jonathan/Documents/CountryWiseAnalytics/'
        UsersCountry = {('Europe', 'NL', 'Netherlands'): 231, ('Europe', 'GB', 'United Kingdom'): 2636}
        for key, value in UsersCountry.iteritems():
            continent = key[0]
            continentMenu = continents.get(continent)
            if continentMenu is None:
                continentMenu = self.menuCountry.addMenu(continent)
                continents[continent] = continentMenu
            country = key[2]
            CT = key[1]
            countryAction = QtGui.QAction(QtGui.QIcon(CT.lower() + '.png'), country, MainWindow)
            countryAction.setStatusTip('uAnalyse ' + country)
            countryAction.triggered.connect(lambda: self.countryAction(country))
            if country in popularcountries:
                print(CT.lower() + '.png')
                self.menuPopular_Countries.addAction(countryAction)
            else:
                continentMenu.addAction(countryAction)

        self.menubar.addAction(self.menuCountry.menuAction())
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.menuCountry.setTitle(_translate("MainWindow", "Country", None))
        self.menuPopular_Countries.setTitle(_translate("MainWindow", "Popular Countries", None))
        self.actionAll_Countries.setText(_translate("MainWindow", "All Countries", None))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

这段代码没有太多要解释的。错误可能出现在以continents = {} 开头的块中,因为这是定义countryAction 的地方。

【问题讨论】:

    标签: python user-interface debugging pyqt pyqt4


    【解决方案1】:

    您的代码似乎对我有用。我在 x86_64 上使用 CentOS-7:

    jkelly@centos:~$ rpm -qi PyQt4 版本:4.10.1 发布:13.el7

    【讨论】:

    • 它运行了,但是无论您点击荷兰还是英国,您是否都没有看到标题为“英国”的窗口?
    • 没错。如果我使用函数返回 lambda,它就可以工作。
       def cfunc(self, country): return lambda x: self.countryAction(country) ... countryAction.triggered.connect(self.cfunc(country)) 
    • 还必须将国家作为参数添加到 self.countryAction
    【解决方案2】:

    你可能需要使用 partial 而不是 lambda

    from functools import partial 
    countryAction.triggered.connect(partial(self.countryAction, country))
    

    【讨论】:

    • 谢谢,这很好用。你能解释一下它背后的逻辑吗?是否与 lambda 的效果有关,因为该函数仅在被单击时才被调用,因此总是触发最后一个 countryAction?
    • 是的,我也想知道。 lambda 函数不是在所有上下文中都存在吗?
    猜你喜欢
    • 1970-01-01
    • 2021-06-27
    • 2018-11-17
    • 2013-01-12
    • 2020-09-25
    • 2023-03-20
    • 1970-01-01
    • 2021-03-05
    • 1970-01-01
    相关资源
    最近更新 更多