有没有办法在应用程序关闭时存储UI资产,然后我可以在下次打开应用程序时加载?

时间:2016-04-04 15:39:02

标签: python python-2.7 user-interface pyqt4

在PyQt4中,我在滚动区域中构建一个大型列表,这需要10秒钟。目前应用程序在构建时挂起,从我的理解,我不能在主线程以外的线程中构建gui对象。有没有办法让这个过程更优雅?我可以绕过'主要线程之外的'no gui建筑'吗?或者也许存储这些gui对象并在我再次启动应用程序后读取它们?我最初使用uic.loadUi()来构建主窗口。

这是MainWindow和buildMatchHistory代码:

class MainWindow(QMainWindow):

def __init__(self):

    global summonerName, summonerNameFull, summonerId, summonerRegion, summonerRank, apiKey
    super(QMainWindow,  self).__init__()

    # Load UI
    fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\MainWindow.ui' 
    self.ui = uic.loadUi(fileLocation,  self)

    # Connect the Refresh match history button to the appropriate method and set the window icon
    self.refreshMatchHistoryButton.clicked.connect(self.refreshMatchHistory)
    self.setWindowIcon(QIcon('app_icon.png'))

    self.ui.show()

    self.matchHistoryBuilder = MatchHistoryBuilder()

    # If match_history.txt exists, call buildMatchHistory. If not, initialize match history files, then call buildMatchHistory.
    fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
    isFile = os.path.isfile(fileLocation)
    if isFile:
        self.buildMatchHistory()
        pass
    else:

        # Pull match history and store in match_history.txt
        fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
        with open(fileLocation, 'w') as newFile:
            matchHistoryData = self.matchHistoryBuilder.getMatchHistory(summonerId)
            json.dump(matchHistoryData, newFile)
        numberOfMatches = matchHistoryData["totalGames"]

        # Create a progress bar to show progress of pulling match history data into files
        self.initMatchHistoryProgressDialog = QProgressDialog(self)
        self.initMatchHistoryProgressDialog.setMinimum(1)
        self.initMatchHistoryProgressDialog.setMaximum(numberOfMatches)
        self.initMatchHistoryProgressDialog.setFixedSize(600, 300)
        self.initMatchHistoryProgressDialog.setWindowTitle("Getting match history data")
        self.initMatchHistoryProgressDialog.show()

        # Spawn a new thread that initializes the match history files. When the thread is finished, call buildMatchHistory().
        self.initMatchHistoryWorkerThread = QThread(self)
        self.initMatchHistory = InitMatchHistory()
        self.initMatchHistory.moveToThread(self.initMatchHistoryWorkerThread)
        self.initMatchHistory.matchDetailsPulled.connect(self.incrementProgressBar)
        QObject.connect(self.initMatchHistoryWorkerThread, SIGNAL('started()'), self.initMatchHistory.run)
        QObject.connect(self.initMatchHistory, SIGNAL('finished()'), self.initMatchHistoryWorkerThread.quit)
        QObject.connect(self.initMatchHistory, SIGNAL('finished()'), self.initMatchHistory.deleteLater)
        QObject.connect(self.initMatchHistory, SIGNAL('finished()'), self.buildMatchHistory)
        QObject.connect(self.initMatchHistoryWorkerThread, SIGNAL('finished()'), self.initMatchHistoryWorkerThread.deleteLater)
        self.initMatchHistoryWorkerThread.start()

def buildMatchHistory(self):
    # This method takes whatever matches are in match_history.txt, calls MatchHistoryBuilder.buildMatch() on each, 
    # and builds the GUI objects for the match history into the matchHistoryScrollArea.
    # Globals: self.matchHistoryBuilder

    print "Entered buildMatchHistory"

    # Open match_history.txt and read json data into matchHistoryData
    fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
    with open(fileLocation,  'r') as f:
        matchHistoryData = json.load(f)
    matchHistoryData = matchHistoryData["matches"]

    # Scroll Area Properties
    self.matchHistory = self.ui.matchHistoryScrollArea
    self.matchHistory.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
    self.matchHistory.setWidgetResizable(True)

    # Container Widget       
    widget = QWidget()
    # Layout of Container Widget
    layout = QVBoxLayout()
    for matchIndex, matchInstance in enumerate(matchHistoryData):
        matchId = matchInstance["matchId"]
        match = self.matchHistoryBuilder.buildMatch(summonerId, matchIndex, matchId)
        layout.addWidget(match)
    widget.setLayout(layout)

    self.matchHistory.setWidget(widget)

MatchHistoryBuilder部分:

class MatchHistoryBuilder(QObject):

def __init__(self):
    super(QObject,  self).__init__()
    #self.mainWindow = mainWindow
    config = SafeConfigParser()
    configFileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + "\config.ini"
    config.read(configFileLocation)
    global apiKey
    apiKey = str(config.get('main',  'apiKey'))
    if not apiKey:
        # Pull api_key from internal file
        print "Was forced to use api_key.txt in MatchHistoryBuilder"
        apiKeyFileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + "\\api_key.txt"
        with open(apiKeyFileLocation, 'r') as f:
            apiKey = f.read()
        if not apiKey:
            print "no API Key available"

def buildMatch(self, summonerId, matchIndex, matchId):
    # This method takes the matchIndex and matchId as an input, builds a match object, and returns it. 
    # Globals: none

    # Open match_history.txt and load json data to matchHistoryData
    fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
    with open(fileLocation,  'r') as f:
        matchHistoryData = json.load(f)

    # If match_history_details.txt isn't yet a file, create it
    fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history_details.txt'
    isFile = os.path.isfile(fileLocation)
    if not isFile:
        with open(fileLocation, 'w') as newFile:
            print "Created match_history_details.txt"
            matchHistoryDetails = {}
            json.dump(matchHistoryDetails, newFile)

    # Open match_history_details and check whether we have match data for the matchID in question. If we do, 
    # continue. If not, call getMatchDetails for the match and store that data in match_history_details.txt.
    with open(fileLocation, 'r') as f:
        matchHistoryDetails = json.load(f)
    if str(matchId) not in matchHistoryDetails.keys():
        matchDetails = self.getMatchDetails(summonerId, matchId)
        while not matchDetails:
            time.sleep(1)
            matchDetails = self.getMatchDetails(summonerId, matchId)
        matchHistoryDetails[matchId] = matchDetails
        with open(fileLocation, 'w') as f:
            json.dump(matchHistoryDetails, f)

    # Load champion name from getChampionName() and lane from matchHistoryData
    championId = matchHistoryData["matches"][matchIndex]["champion"]
    championName = self.getChampionName(championId)
    lane = matchHistoryData["matches"][matchIndex]["lane"].lower().capitalize()

    # Build the match GroupBox itself with the champion name as the title
    match = QGroupBox(championName)
    match.setFixedHeight(170)
    match.setFixedWidth(940)

    # For each match, build GroupBox's for statistics and set their sizes, positions, and object names
    scoreBox = QGroupBox(match)
    scoreBox.setFixedWidth(130)
    scoreBox.setFixedHeight(60)
    scoreBox.setGeometry(QRect(280, 20, 130, 60))
    scoreBox.setAlignment(Qt.AlignCenter)
    scoreBox.setObjectName("scoreBox")
    killParticipationPercentBox = QGroupBox(match)
    killParticipationPercentBox.setFixedWidth(130)
    killParticipationPercentBox.setFixedHeight(60)
    killParticipationPercentBox.setGeometry(QRect(440, 20, 130, 60))
    killParticipationPercentBox.setAlignment(Qt.AlignCenter)
    killParticipationPercentBox.setObjectName("killParticipationPercentBox")
    goldPerMinBox = QGroupBox(match)
    goldPerMinBox.setFixedWidth(130)
    goldPerMinBox.setFixedHeight(60)
    goldPerMinBox.setGeometry(QRect(440, 90, 130, 60))
    goldPerMinBox.setAlignment(Qt.AlignCenter)
    goldPerMinBox.setObjectName("goldPerMinBox")
    kdaBox = QGroupBox(match)
    kdaBox.setFixedWidth(130)
    kdaBox.setFixedHeight(60)
    kdaBox.setGeometry(QRect(280, 90, 130, 60))
    kdaBox.setAlignment(Qt.AlignCenter)
    kdaBox.setObjectName("kdaBox")
    wardScoreBox = QGroupBox(match)
    wardScoreBox.setFixedWidth(130)
    wardScoreBox.setFixedHeight(60)
    wardScoreBox.setGeometry(QRect(600, 20, 130, 60))
    wardScoreBox.setAlignment(Qt.AlignCenter)
    wardScoreBox.setObjectName("wardScoreBox")
    csPerMinBox = QGroupBox(match)
    csPerMinBox.setFixedWidth(130)
    csPerMinBox.setFixedHeight(60)
    csPerMinBox.setGeometry(QRect(600, 90, 130, 60))
    csPerMinBox.setAlignment(Qt.AlignCenter)
    csPerMinBox.setObjectName("groupBox_7")
    changeInLPLabel = QLabel(match)
    changeInLPLabel.setGeometry(QRect(820, 90, 101, 61))
    changeInLPLabel.setObjectName("changeInLP")
    laneLabel = QLabel(match)
    laneLabel.setGeometry(QRect(20, 100, 141, 51))
    laneLabel.setStyleSheet("font: 10pt \"Verdana\";")
    laneLabel.setObjectName("lane")

    # Set titles of each item
    scoreBox.setTitle("score")
    killParticipationPercentBox.setTitle("Kill part. %")
    goldPerMinBox.setTitle("gold/min")
    kdaBox.setTitle("KDA")
    wardScoreBox.setTitle("ward score")
    csPerMinBox.setTitle("cs/min")
    changeInLPLabel.setText("+lp")
    laneLabel.setText(lane)

    return match

工人主题:

class InitMatchHistory(QObject):

    matchDetailsPulled = pyqtSignal(object)

    def __init__(self):
        super(QObject,  self).__init__()

    def run(self):

        configFileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + "\config.ini"
        config = SafeConfigParser()
        config.read(configFileLocation)
        self.summonerId = config.get('main',  'summonerId')

        self.matchHistoryBuilder = MatchHistoryBuilder()

        # If match_history_details.txt isn't yet a file, create it
        fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history_details.txt'
        isFile = os.path.isfile(fileLocation)
        if not isFile:
            with open(fileLocation, 'w') as newFile:
                print "Created match_history_details.txt"
                matchHistoryDetails = {}
                json.dump(matchHistoryDetails, newFile)

        # Open match_history.txt and read json data into matchHistoryData
        fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
        with open(fileLocation,  'r') as f:
            matchHistoryData = json.load(f)
        matchHistoryData = matchHistoryData["matches"]

        # For each match in match history, open match_history_details and check whether we have match data for the 
        # matchID in question. If not, call getMatchDetails for the match and store that data in match_history_details.txt.
        fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history_details.txt'
        with open(fileLocation, 'r') as f:
                matchHistoryDetails = json.load(f)
        for matchIndex, matchInstance in enumerate(matchHistoryData):
            matchId = matchInstance["matchId"]
            if str(matchId) not in matchHistoryDetails.keys():
                matchDetails = self.matchHistoryBuilder.getMatchDetails(self.summonerId, matchId)
                if not matchDetails:
                    time.sleep(10)
                    matchDetails = self.matchHistoryBuilder.getMatchDetails(self.summonerId, matchId)
                matchHistoryDetails[matchId] = matchDetails
                self.matchDetailsPulled.emit(str(matchIndex))
                with open(fileLocation, 'w') as f:
                    json.dump(matchHistoryDetails, f)

class RefreshMatchHistory(QObject):

    def __init__(self):
        super(QObject,  self).__init__()

    def run(self):

        configFileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + "\config.ini"
        config = SafeConfigParser()
        config.read(configFileLocation)
        self.summonerId = config.get('main',  'summonerId')

        self.matchHistoryBuilder = MatchHistoryBuilder()

        try:

            # Open match_history.txt and read json data into matchHistoryData
            fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
            with open(fileLocation,  'r') as f:
                    oldMatchHistoryData = json.load(f)
            oldMatches = oldMatchHistoryData["matches"]

            # Call getMatchHistory and for any new matches, call getMatchDetails and update match_history_details.txt
            newMatchHistoryData = self.matchHistoryBuilder.getMatchHistory(self.summonerId)
            newMatches = newMatchHistoryData["matches"]
            numberOfNewMatches = newMatchHistoryData["totalGames"] - oldMatchHistoryData["totalGames"]
            fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history_details.txt'
            with open(fileLocation, 'r') as f:
                    matchHistoryDetails = json.load(f)
            while numberOfNewMatches > 0:
                matchId = newMatches[numberOfNewMatches-1]["matchId"]
                if str(matchId) not in matchHistoryDetails.keys():
                    matchDetails = self.getMatchDetails(self.summonerId, matchId)
                    if not matchDetails:
                        time.sleep(10)
                        matchDetails = self.getMatchDetails(self.summonerId, matchId)
                    matchHistoryDetails[matchId] = matchDetails
                numberOfNewMatches -= 1
            with open(fileLocation, 'w') as f:
                json.dump(matchHistoryDetails, f)

            # When done, store the new match history in match_history.txt
            fileLocation = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) + '\match_history.txt'
            with open(fileLocation, 'w') as f:
                json.dump(newMatchHistoryData, f)

        except IOError:
            print "One or both of the match history files are missing, from refreshMatchHistory"

0 个答案:

没有答案