class CharacterOverviewWidget(QPushButton): def __init__(self, user, parent=None): super(CharacterOverviewWidget, self).__init__(parent) self.setAutoFillBackground(True) # self.installEventFilter() self.user = user self.dbHandler = DatabaseHandler() try: self.character = self.dbHandler.getCharacter(user.get_id()) except Exception as e: print("Exception in Character Overview Widget: " + str(e)) if self.character is None: print("Character Overview has a None Character") # Background Color #pal = QPalette() #pal.setColor(self.backgroundRole(), QtCore.Qt.red) #self.setPalette(pal) # Character Image self.characterImage = QLabel() self.pixmap = QPixmap('portrait.png') self.characterImage.setPixmap(self.pixmap.scaled(120, 120)) self.characterImage.resize(120, 120) # Labels self.characterNameLabel = QLabel("Name") self.characterBalanceLabel = QLabel("Balance") self.characterSkillpointsLabel = QLabel("Skillpoints") self.characterSkillRemainingTimeLabel = QLabel("Skill Remaining Time") self.characterSkillNameLabel = QLabel("Skillname") self.characterSkillEndDateLabel = QLabel("Skill End Date") self.characterQueueRemainingTimeLabel = QLabel("Queue Remaining Time") self.setLabels() self.setCharacterPortrait() self.setLabelFonts() vbox = QVBoxLayout() vbox.setSpacing(1) vbox.setAlignment(QtCore.Qt.AlignTop) vbox.addWidget(self.characterNameLabel) vbox.addWidget(self.characterBalanceLabel) vbox.addWidget(self.characterSkillpointsLabel) vbox.addSpacing(10) vbox.addWidget(self.characterSkillRemainingTimeLabel) vbox.addSpacing(5) vbox.addWidget(self.characterSkillNameLabel) vbox.addWidget(self.characterSkillEndDateLabel) vbox.addWidget(self.characterQueueRemainingTimeLabel) hbox = QHBoxLayout() hbox.addWidget(self.characterImage) hbox.addSpacing(10) hbox.addLayout(vbox) hbox.addStretch(1) self.setLayout(hbox) self.set_size_policy() self.startUpdateTimer() def initLayout(self): print("") def setLabels(self): if self.character is not None: self.characterNameLabel.setText(self.character.name) self.characterBalanceLabel.setText( format(self.character.balance, ",") + " ISK") self.characterSkillpointsLabel.setText( format(self.character.total_sp, ",") + " SP") lastSkill = self.dbHandler.getSkillQueueLast(self.user.get_id()) #firstSkill = self.dbHandler.getSkillQueueFirst(self.user.get_id()) #dbThread = threading.Thread(target=self.dbHandler.getQueueFirst, args=(self.user.get_id(),)) #dbThread.daemon = True #dbThread.start() firstSkill = self.dbHandler.getQueueFirst(self.user.get_id()) #print(realFirst) if firstSkill is None: # ToDo: Check for different approach # Character has no SkillQueue #print(self.character.name + " has an empty SkillQueue") SkillRemainingTime = "" SkillName = "" SkillEndDate = "" QueueRemainingTime = "" elif firstSkill.finish_date is None: # Character has an inactive SkillQueue # print(self.character.name + " has an inactive SkillQueue") SkillRemainingTime = "Paused" SkillName = self.dbHandler.getStaticSkillData( firstSkill.skill_id).name + " " + str( firstSkill.finished_level) SkillEndDate = "" QueueRemainingTime = "" else: # Character has an active SkillQueue #print(self.character.name + " has an active SkillQueue") SkillRemainingTime = service.tools.getSkillRemainingTime( firstSkill) SkillName = self.dbHandler.getStaticSkillData( firstSkill.skill_id).name + " " + str( firstSkill.finished_level) SkillEndDate = service.tools.formatDateTime( firstSkill.finish_date + config.TIME_DIFFERENCE) QueueRemainingTime = "Queue ends in " + service.tools.getSkillRemainingTime( lastSkill) self.characterSkillRemainingTimeLabel.setText(SkillRemainingTime) self.characterSkillNameLabel.setText(SkillName) self.characterSkillEndDateLabel.setText(SkillEndDate) self.characterQueueRemainingTimeLabel.setText(QueueRemainingTime) def setCharacterPortrait(self): # Gets url to the character Portrait from db and sets the shown image to it # ToDo: Needs to be changed, so that the image is be save on the harddrive try: portraitUrl = self.dbHandler.getCharacterPortrait( self.user.get_id()) if portraitUrl is not None: data = request.urlopen(portraitUrl.px128x128).read() self.pixmap.loadFromData(data) self.characterImage.setPixmap(self.pixmap.scaled(120, 120)) else: print("No portrait URL for " + self.user.CharacterName + " in the Database") #data = request.urlopen("https://pixabay.com/de/pinguin-vogel-tier-tierwelt-k%C3%A4lte-42936/").read() except Exception as e: print("Exception in CharacterOverview Widget: " + str(e)) def eventFilter(self, object, event): if event.type() == QtCore.QEvent.HoverMove: print("Mouseover") def set_size_policy(self): self.setMaximumSize(350, 150) self.setMinimumSize(350, 150) def setLabelFonts(self): self.characterNameLabel.setFont(QFont("Arial", 14, QFont.Bold)) self.characterBalanceLabel.setFont(QFont("Arial", 12, QFont.Bold)) self.characterSkillpointsLabel.setFont(QFont("Arial", 10)) self.characterSkillRemainingTimeLabel.setFont(QFont("Arial", 10)) def startUpdateTimer(self): self.timer = QtCore.QTimer() self.timer.timeout.connect(self.setLabels) self.timer.setSingleShot(False) self.timer.start(1000) def updateLabel(self): self.characterBalanceLabel.update() self.characterSkillpointsLabel.update() self.characterSkillRemainingTimeLabel.update() self.characterSkillNameLabel.update() self.characterSkillEndDateLabel.update() self.characterQueueRemainingTimeLabel.update() def enterEvent(self, QEvent): # here the code for mouse hover pass def leaveEvent(self, QEvent): # here the code for mouse leave pass
class SkillPlannerWindow(QMainWindow): def __init__(self, plan_id, parent=None): super(SkillPlannerWindow, self).__init__(parent) self.dbHandler = DatabaseHandler() self.plan = None self.loadPlan(plan_id) if self.plan is not None: self.user_id = self.plan.owner_id self.character_name = self.dbHandler.getCharacter(self.user_id).name self.set_main_window() self.initLayout() def set_main_window(self): # Standard Values for this Window standard_width = 860 standard_height = 600 minimum_width = 544 minimum_height = 300 """Sets the size policies of the main window""" self.resize(standard_width, standard_height) size_policy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) size_policy.setHorizontalStretch(0) size_policy.setVerticalStretch(0) size_policy.setHeightForWidth(self.sizePolicy().hasHeightForWidth()) self.setSizePolicy(size_policy) self.setMinimumSize(QSize(minimum_width, minimum_height)) # self.setMaximumSize(QSize(standard_width, standard_height)) # main window icon self.setWindowIcon(QIcon(config.APP_ICON)) #self.setWindowTitle(self.character_name + self.plan.name + config.APP_NAME + " Skill Planner") # ToDo: Add plan owner and plan name def initLayout(self): self.centralwidget = QWidget(self) self.layout = QVBoxLayout(self.centralwidget) self.layout.setContentsMargins(20, 20, 20, 20) self.layout.setSpacing(5) self.setCentralWidget(self.centralwidget) self.plansCombo = QComboBox(self) self.plansCombo.addItem("Select Plan") self.plansCombo.addItem("New Plan") self.plansCombo.addItem("Create Plan from Skill Queue") self.plansCombo.activated.connect(self.handlePlansCombo) self.fillPlansCombo() self.layout.addLayout(self.firstLineOptions()) def firstLineOptions(self): ''' First Line Options: Select Plan Export Plan to Delete Plan Print Plan (drucken) Copy to clipboard Implant calculator atrribute optimizer :return: ''' hbox = QHBoxLayout() hbox.addWidget(self.plansCombo) hbox.addStretch(1) return hbox def skillPlannerTabs(self): print("") def handlePlansCombo(self, index): itemData = self.plansCombo.itemData(index) itemText = self.plansCombo.itemText(index) if itemData is not None: print(self.plansCombo.itemData(index)) def fillPlansCombo(self): plan_list = self.dbHandler.getCharacterPlans(self.user_id) for plan in plan_list: self.plansCombo.addItem(plan.name, plan.id) self.layout.update() def loadPlan(self, plan_id): if plan_id is not None: self.plan = self.dbHandler.getPlan(plan_id)
class CharacterTabWidget(QWidget): def __init__(self, user, parent=None): super(CharacterTabWidget, self).__init__(parent) self.parent = parent self.user = user self.dbHandler = DatabaseHandler() try: self.character = self.dbHandler.getCharacter(user.get_id()) self.attributes = self.dbHandler.getCharacterAttributes(user.get_id()) except Exception as e: print("Exception in CharacterTab: " + str(e)) if self.character is None: print("Character Tab has a None Character") else: self.layout = self.createLayout() self.layout.setSpacing(0) self.setLayout(self.layout) self.startUpdateTimer() def getUser(self): # returns the user_id for this character_tab return self.user.id def startUpdateTimer(self): self.timer = QtCore.QTimer() self.timer.timeout.connect(self.updateLabels) self.timer.setSingleShot(False) self.timer.start(1000) def updateLabels(self): self.layout.update() def createLayout(self): vBox = QVBoxLayout() vBox.addLayout(self.horizontalTop()) vBox.addSpacing(5) vBox.addLayout(self.horizontalMiddle()) self.functionTab = FunctionTabWidget(self.user) vBox.addWidget(self.functionTab) #vBox.addStretch(1) return vBox def horizontalTop(self): # Character Image characterImage = QLabel() pixmap = QPixmap(self.getCharacterPortrait()) if pixmap is None: pixmap = QPixmap('portrait.png') characterImage.setPixmap(pixmap.scaled(150, 150)) characterImage.resize(150, 150) hBox = QHBoxLayout() hBox.setAlignment(QtCore.Qt.AlignTop) hBox.addWidget(characterImage) hBox.addSpacing(5) # Character General Information vBox = QVBoxLayout() #vBox.setAlignment(QtCore.Qt.AlignLeft) vBox.setAlignment(QtCore.Qt.AlignTop) vBox.setSpacing(0) vBox.setContentsMargins(0,0,0,0) nameLabel = QLabel(self.character.name) nameLabel.setFont(QFont("Arial", 14, QFont.Bold)) balanceLabel = QLabel("Balance: " + format(self.character.balance) + " ISK") corpLabel = QLabel("Corporation: ") allyLabel = QLabel("Alliance: ") secLabel = QLabel("Security Status: " + str(round(self.character.security_status, 2))) fatigueLabel = QLabel("Jump Fatigue: ") shipLabel = QLabel("Active Ship: ") locationLabel = QLabel("Located in: ") dockedLabel = QLabel("Docked at: ") vBox.addWidget(nameLabel) vBox.addWidget(balanceLabel) vBox.addWidget(corpLabel) vBox.addWidget(allyLabel) vBox.addWidget(secLabel) vBox.addWidget(fatigueLabel) vBox.addWidget(shipLabel) vBox.addWidget(locationLabel) vBox.addWidget(dockedLabel) #vBox.addStretch(1) hBox.addLayout(vBox) hBox.addStretch(1) #ToDo: Update Timer + Force update button (When will the next update occur) return hBox def horizontalMiddle(self): # Account Subscription Status vBox1 = QVBoxLayout() vBox1.setAlignment(QtCore.Qt.AlignTop) subscriptionStatusLabel = QLabel("Account Status: " + "Unknown") #subsriptionTimeLabel = QLabel("Remaining Time") subscriptionStatusLabel.setFixedWidth(155) # To indent the Middle hBox. size: pixmap + spacing vBox1.addWidget(subscriptionStatusLabel) #vBox1.addWidget(subsriptionTimeLabel) #vBox1.addStretch(1) # Character Stats vBox2 = QVBoxLayout() vBox2.setAlignment(QtCore.Qt.AlignTop) intelligenceLabel = QLabel("Intelligence: " + offset(8) + str(self.attributes.intelligence)) # 12 perceptionLabel = QLabel("Perception: " + offset(9) + str(self.attributes.perception)) # 10 charismaLabel = QLabel("Charisma: " + offset(11) + str(self.attributes.charisma)) # 8 willpowerLabel = QLabel("Willpower: " + offset(11) + str(self.attributes.willpower)) # 9 memoryLabel = QLabel("Memory: " + offset(13) + str(self.attributes.memory)) # 6 intelligenceLabel.setFixedWidth(120) vBox2.addWidget(intelligenceLabel) vBox2.addWidget(perceptionLabel) vBox2.addWidget(charismaLabel) vBox2.addWidget(willpowerLabel) vBox2.addWidget(memoryLabel) #vBox2.addStretch(1) #Clone Jump Status vBox3 = QVBoxLayout() vBox3.setAlignment(QtCore.Qt.AlignTop) bonusRemapLabel = QLabel("Bonus Remap: " + str(self.attributes.bonus_remaps)) neuralRemapLabel = QLabel("Next Neural Remap: " + remapTime(self.attributes.accrued_remap_cooldown_date)) cloneJumpLabel = QLabel("Next Clone Jump: ") vBox3.addWidget(bonusRemapLabel) vBox3.addWidget(neuralRemapLabel) vBox3.addWidget(cloneJumpLabel) #vBox3.addStretch(1) # Skills Statistics vBox4 = QVBoxLayout() vBox4.setAlignment(QtCore.Qt.AlignTop) # ToDo: Include the completed Skills in SkillQueue knownSkillsLabel = QLabel("Known Skills: " + str(self.dbHandler.getKnownSkillsCount(self.user))) skillsAt5Label = QLabel("Skills at Level V: " + str(self.dbHandler.getSkillsAtV(self.user))) totalSPLabel = QLabel("Total SP: " + format(self.character.total_sp)) if self.character.unallocated_sp is None: tmp = 0 else: tmp = self.character.unallocated_sp unallocatedSP = QLabel("Unallocated SP: " + format(tmp)) vBox4.addWidget(knownSkillsLabel) vBox4.addWidget(skillsAt5Label) vBox4.addWidget(totalSPLabel) vBox4.addWidget(unallocatedSP) #vBox4.addStretch(1) # Complete horizontal Middle hBox = QHBoxLayout() hBox.addLayout(vBox1) hBox.addLayout(vBox2) hBox.addSpacing(20) hBox.addLayout(vBox3) hBox.addStretch(1) hBox.addLayout(vBox4) return hBox def getCharacterPortrait(self): # Gets url to the character Portrait from db and sets the shown image to it # ToDo: Needs to be changed, so that the image is be save on the harddrive pixmap = QPixmap() try: portraitUrl = self.dbHandler.getCharacterPortrait(self.user.get_id()) if portraitUrl is not None: data = request.urlopen(portraitUrl.px256x256).read() pixmap.loadFromData(data) else: print("No portrait URL for " + self.user.CharacterName + " in the Database") except Exception as e: print("Exception in CharacterTabWidget.getCharacterPortrait: " + str(e)) return pixmap