Запуск приложения при ошибке
У меня есть приложение, в котором есть погода, которая берется с OpenWeatherMap.
Как сделать так, чтобы при ошибке с OpenWeatherMap (превышен лимит запросов) и при выключенном интернете приложение все равно открывалось?
Вот ссылка на само приложение: https://github.com/ivapop1/Weather-PyQt5
Вот скрин ошибки при отсутствии интернет соединения:
Ответы (3 шт):
class WeatherData(QThread):
req = weather.today()
Вот тут ошибка. Класс не инициализируется без первого запроса!
Выстави умолчания совместимого типа:
class WeatherData(QThread):
req = {} # тут можно None
temp = 0
#и тд..
Оно в интерфейсе покажет 0, и через мгновение обновится. Начни с этого.
Дальше напиши стек с виджетом "загрузка" и поставь его пока not req выше погоды. Потом изучай на сигналы-слоты - это основа qt.
1 . Вам надо переделать модуль root.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>from</class> ??? from
<widget class="QWidget" name="from"> ??? from
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>370</width>
<height>535</height>
...
from - это зарезервированное слово и абы как и абы где
его использовать нельзя !!!
Я его конвертировал pyuic5 root.ui -o root_ui.py -x
и вручную поправил и использовал в приложении !!!
# vvvvvvv
class Ui_Form(object):
# vvvv
def setupUi(self, Form):
# vvvv
Form.setObjectName("Form")
Form.resize(370, 535)
...
2 . Обратите ВНИМАНИЕ !!!
В модуле weather.py
...
print(f'\n\n def today(): g = {g.ok} ') # +++
if not g.ok: # +++
return False # +++
...
print(f'def week(): g = {g.ok}') # +++
if not g.ok: # +++
return False # +++
...
когда нет коннекта возвращаем False
В модуле main.py
...
if req_week and req: # !!!
self.week = req_week
self.temp = req['temp']
self.feels = req['feels']
self.pres = req['pressure']
self.speed = str(req['wind']['speed'])
self.city = req['city']
self.type = req['dis']
else:
self.mySignal.emit()
...
3 . и другие нужные вещи по тексту.
main.py
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox
from PyQt5 import uic, QtCore, QtTest, QtWidgets, QtGui
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QThread, pyqtSignal
import weather
# ?import time
import datetime
from weather import DAYS
# +++ pyuic5 root.ui -o root_ui.py -x
from root_ui import Ui_Form # +++
#два класса с числами Фобаначе , для правного визуала
H_show = [
155,156,157,158,
160,168,181,202,
236,291,380,400,
440,500,535,
]
H_hide = [
155,156,157,158,
160,168,181,202,
236,291,380,400,
440,500,535,
]
class WeatherData(QThread):
req = weather.today()
temp = req['temp']
feels = req['feels']
pres = req['pressure']
speed = str(req['wind']['speed'])
city = req['city']
type = req['dis']
week = weather.week()
mySignal = pyqtSignal() # +++
def __init__(self):
# QThread.__init__(self)
super().__init__()
def run(self):
while True:
req = weather.today()
req_week = weather.week()
if req_week and req: # !!!
self.week = req_week
self.temp = req['temp']
self.feels = req['feels']
self.pres = req['pressure']
self.speed = str(req['wind']['speed'])
self.city = req['city']
self.type = req['dis']
else:
self.mySignal.emit()
# time.sleep(1800) #
self.msleep(1000 * 7) # 1000 * 60 * 30 = 1800сек = 30мин
class MyRoot(QWidget, Ui_Form): # +++
def __init__(self): # +++
super().__init__() # +++
self.setupUi(self) # +++
class App(QWidget):
show_more = True
def __init__(self):
super().__init__()
self.weather = WeatherData()
self.weather.mySignal.connect(self._error) # +++
self.weather.start()
self.set()
self.setData()
self.setMore()
def _error(self): # +++
print(f'\n"Проверьте доступ в интернет !!!"\n') # +++
def set(self):
# self.w_root = uic.loadUi('root.ui')
self.w_root = MyRoot()
self.w_root.show() # +++
self.w_root.btn_more.clicked.connect(self.setHeight)
#устанавливаем значение на сегодня
def setData(self):
self.w_root.l_temp.setText(str(self.weather.temp) + '°C')
self.w_root.l_fell.setText(self.weather.feels)
self.w_root.l_pres.setText(self.weather.pres)
self.w_root.l_wind.setText(self.weather.speed + 'м/с')
self.w_root.l_city.setText(self.weather.city)
self.w_root.l_type.setText(self.weather.type)
#иконка погоды
px_logo = QPixmap(f'Ok.png')
self.w_root.l_logo.setPixmap(px_logo)
#день недели
today = DAYS[datetime.datetime.today().weekday()]
self.w_root.l_day.setText(today['title'])
color = today['color']
self.w_root.l_day.setStyleSheet(f'color:{color}')
def setHeight(self):
if self.w_root.height() >= 300:
self.show_more = False
if self.show_more:
for i in H_hide:
if self.w_root.height() > i:
continue
self.w_root.resize(444, i)
self.w_root.btn_more.move(0, i-26)
self.w_root.l_day.move(8,i-18)
QtWidgets.QApplication.processEvents()
# ? time.sleep(.02)
self.show_more = False
else:
for i in reversed(H_show):
self.w_root.resize(444, i)
self.w_root.btn_more.move(0, i-26)
self.w_root.l_day.move(8,i-18)
QtWidgets.QApplication.processEvents()
# ? time.sleep(.02)
self.show_more = True
App.show_more = self.show_more
def setMore(self):
for i in self.weather.week:
w_day = uic.loadUi('day.ui')
w_day.setObjectName('w_day_' + str(i['num']))
w_day.l_title.setText(i['title'])
w_day.l_temp.setText(str(round(i['temp'])) + '°C')
w_day.l_type.setText(i['type'])
w_day.l_title.setStyleSheet('color: ' + i['color'] + '; background-color: none; border: none')
if i['active']:
w_day.setStyleSheet('border: 1px solid' + i['color'])
else:
w_day.setStyleSheet('border: none')
self.w_root.box.addWidget(w_day)
self.w_root.box.addStretch()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
ex = App()
ex.show
sys.exit(app.exec_())
weather.py
# weather v 1.0
import requests
import geocoder
import datetime
API_KEY = 'cf64041397ba4128f1a2426cd3e11397'
HOST = 'https://api.openweathermap.org/data/2.5/'
DAYS = [
{'num': 0 , 'title':'понедельник', 'active': False , 'color' : '#2d5664', 'order': [0,1,2,3,4,5,6], 'temp': 0, 'type': '-'},
{'num': 1 , 'title':'вторник', 'active': False , 'color' : '#2d5664', 'order': [1,2,3,4,5,6,0], 'temp': 0, 'type': '-'},
{'num': 2 , 'title':'среда', 'active': False , 'color' : '#2d5664', 'order': [2,3,4,5,6,0,1], 'temp': 0, 'type': '-'},
{'num': 3 , 'title':'четверг', 'active': False , 'color' : '#2d5664', 'order': [3,4,5,6,0,1,2], 'temp': 0, 'type': '-'},
{'num': 4 , 'title':'пятница', 'active': False , 'color' : '#2d5664', 'order': [4,5,6,0,1,2,3], 'temp': 0, 'type': '-'},
{'num': 5 , 'title':'суббота', 'active': False , 'color' : '#d0130d', 'order': [5,6,0,1,2,3,4], 'temp': 0, 'type': '-'},
{'num': 6 , 'title':'воскресенье', 'active': False , 'color' : '#d0130d', 'order': [6,0,1,2,3,4,5], 'temp': 0, 'type': '-'},
]
def today():
g = geocoder.ip('199.7.157.0')
print(f'\n\n def today(): g = {g.ok} ') # +++
if not g.ok: # +++
return False # +++
city = g.city
lat = g.lat
lon = g.lng
req = requests.get(f'{HOST}weather?lat={lat}&lon={lon}&appid={API_KEY}&units=metric&lang=ru').json()
res={
'city' : req['name'],
'dis' : req['weather'][0]['description'],
'temp' : int(round(req['main']['temp'])),
'feels': str(round(req['main']['feels_like']))+ '°С',
'pressure': str(round(req['main']['pressure'] / 1000 * 750 , 2)),
'wind' : req['wind'],
}
return res
def week():
today = datetime.datetime.today()
DAYS[today.weekday()]['active'] = True
for i in DAYS:
if DAYS[today.weekday()]['active']:
order = DAYS[today.weekday()]['order']
g = geocoder.ip('199.7.157.0')
print(f'def week(): g = {g.ok}') # +++
if not g.ok: # +++
return False # +++
city = g.city
lat = g.lat
lon = g.lng
req = requests.get(f'{HOST}onecall?/exclude=daily&lat={lat}&lon={lon}&appid={API_KEY}&units=metric&lang=ru').json()
res = [DAYS[i] for i in order]
for i in req['daily']:
index = req['daily'].index(i)
if index ==7:
break
res[index]['temp'] = round(i['temp']['day'])
res[index]['type'] = i['weather'][0]['description']
return res
root_ui.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(370, 535)
Form.setMinimumSize(QtCore.QSize(370, 154))
Form.setMaximumSize(QtCore.QSize(370, 535))
font = QtGui.QFont()
font.setFamily("Century Gothic")
font.setPointSize(35)
Form.setFont(font)
self.l_temp = QtWidgets.QLabel(Form)
self.l_temp.setGeometry(QtCore.QRect(6, 6, 131, 81))
self.l_temp.setMinimumSize(QtCore.QSize(131, 80))
self.l_temp.setMaximumSize(QtCore.QSize(131, 81))
font = QtGui.QFont()
font.setPointSize(30)
self.l_temp.setFont(font)
self.l_temp.setObjectName("l_temp")
self.l_city = QtWidgets.QLabel(Form)
self.l_city.setGeometry(QtCore.QRect(4, 4, 131, 25))
self.l_city.setMinimumSize(QtCore.QSize(131, 24))
self.l_city.setMaximumSize(QtCore.QSize(131, 25))
font = QtGui.QFont()
font.setPointSize(13)
self.l_city.setFont(font)
self.l_city.setObjectName("l_city")
self.l_type = QtWidgets.QLabel(Form)
self.l_type.setGeometry(QtCore.QRect(6, 63, 175, 25))
self.l_type.setMinimumSize(QtCore.QSize(175, 24))
self.l_type.setMaximumSize(QtCore.QSize(175, 25))
font = QtGui.QFont()
font.setPointSize(9)
self.l_type.setFont(font)
self.l_type.setObjectName("l_type")
self.l_fell = QtWidgets.QLabel(Form)
self.l_fell.setGeometry(QtCore.QRect(-6, 83, 123, 20))
self.l_fell.setMinimumSize(QtCore.QSize(123, 19))
self.l_fell.setMaximumSize(QtCore.QSize(123, 20))
font = QtGui.QFont()
font.setPointSize(12)
font.setBold(False)
font.setUnderline(False)
font.setWeight(50)
font.setStrikeOut(False)
self.l_fell.setFont(font)
self.l_fell.setAlignment(QtCore.Qt.AlignCenter)
self.l_fell.setObjectName("l_fell")
self.l_pres = QtWidgets.QLabel(Form)
self.l_pres.setGeometry(QtCore.QRect(120, 83, 123, 20))
self.l_pres.setMinimumSize(QtCore.QSize(123, 19))
self.l_pres.setMaximumSize(QtCore.QSize(123, 20))
font = QtGui.QFont()
font.setPointSize(12)
self.l_pres.setFont(font)
self.l_pres.setAlignment(QtCore.Qt.AlignCenter)
self.l_pres.setObjectName("l_pres")
self.l_wind = QtWidgets.QLabel(Form)
self.l_wind.setGeometry(QtCore.QRect(246, 83, 123, 20))
self.l_wind.setMinimumSize(QtCore.QSize(123, 19))
self.l_wind.setMaximumSize(QtCore.QSize(123, 20))
font = QtGui.QFont()
font.setPointSize(12)
self.l_wind.setFont(font)
self.l_wind.setAlignment(QtCore.Qt.AlignCenter)
self.l_wind.setObjectName("l_wind")
self.l_temp_1 = QtWidgets.QLabel(Form)
self.l_temp_1.setGeometry(QtCore.QRect(-6, 105, 120, 20))
self.l_temp_1.setMinimumSize(QtCore.QSize(120, 19))
self.l_temp_1.setMaximumSize(QtCore.QSize(120, 20))
font = QtGui.QFont()
font.setPointSize(10)
self.l_temp_1.setFont(font)
self.l_temp_1.setAlignment(QtCore.Qt.AlignCenter)
self.l_temp_1.setObjectName("l_temp_1")
self.l_temp_2 = QtWidgets.QLabel(Form)
self.l_temp_2.setGeometry(QtCore.QRect(120, 105, 122, 20))
self.l_temp_2.setMinimumSize(QtCore.QSize(122, 19))
self.l_temp_2.setMaximumSize(QtCore.QSize(122, 20))
font = QtGui.QFont()
font.setPointSize(10)
self.l_temp_2.setFont(font)
self.l_temp_2.setAlignment(QtCore.Qt.AlignCenter)
self.l_temp_2.setObjectName("l_temp_2")
self.l_temp_3 = QtWidgets.QLabel(Form)
self.l_temp_3.setGeometry(QtCore.QRect(246, 105, 116, 20))
self.l_temp_3.setMinimumSize(QtCore.QSize(116, 19))
self.l_temp_3.setMaximumSize(QtCore.QSize(116, 20))
font = QtGui.QFont()
font.setPointSize(10)
self.l_temp_3.setFont(font)
self.l_temp_3.setAlignment(QtCore.Qt.AlignCenter)
self.l_temp_3.setObjectName("l_temp_3")
self.btn_more = QtWidgets.QPushButton(Form)
self.btn_more.setGeometry(QtCore.QRect(-4, 123, 378, 33))
self.btn_more.setMinimumSize(QtCore.QSize(378, 33))
self.btn_more.setMaximumSize(QtCore.QSize(378, 33))
font = QtGui.QFont()
font.setFamily("Bookman Old Style")
font.setPointSize(11)
font.setBold(False)
font.setItalic(False)
font.setUnderline(False)
font.setWeight(50)
font.setStrikeOut(True)
self.btn_more.setFont(font)
self.btn_more.setStyleSheet("border-color: rgb(198, 198, 198);\n"
"border-color: rgb(160, 160, 160);")
self.btn_more.setAutoDefault(False)
self.btn_more.setDefault(False)
self.btn_more.setFlat(False)
self.btn_more.setObjectName("btn_more")
self.l_day = QtWidgets.QLabel(Form)
self.l_day.setGeometry(QtCore.QRect(4, 132, 111, 16))
font = QtGui.QFont()
font.setPointSize(10)
self.l_day.setFont(font)
self.l_day.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
self.l_day.setObjectName("l_day")
self.l_logo = QtWidgets.QLabel(Form)
self.l_logo.setGeometry(QtCore.QRect(160, 8, 171, 71))
self.l_logo.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
self.l_logo.setText("")
self.l_logo.setAlignment(QtCore.Qt.AlignCenter)
self.l_logo.setObjectName("l_logo")
self.line = QtWidgets.QFrame(Form)
self.line.setGeometry(QtCore.QRect(0, 126, 371, 3))
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.verticalLayoutWidget = QtWidgets.QWidget(Form)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 130, 384, 411))
self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
self.box = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
self.box.setContentsMargins(4, 0, 2, 0)
self.box.setSpacing(0)
self.box.setObjectName("box")
self.l_temp.raise_()
self.l_city.raise_()
self.l_type.raise_()
self.l_fell.raise_()
self.l_pres.raise_()
self.l_wind.raise_()
self.l_temp_1.raise_()
self.l_temp_2.raise_()
self.l_temp_3.raise_()
self.l_logo.raise_()
self.line.raise_()
self.verticalLayoutWidget.raise_()
self.btn_more.raise_()
self.l_day.raise_()
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.l_temp.setText(_translate("Form", "-27 C"))
self.l_city.setText(_translate("Form", "City"))
self.l_type.setText(_translate("Form", "type weather"))
self.l_fell.setText(_translate("Form", "0 C"))
self.l_pres.setText(_translate("Form", "750"))
self.l_wind.setText(_translate("Form", "3 м/с"))
self.l_temp_1.setText(_translate("Form", "ощущается"))
self.l_temp_2.setText(_translate("Form", "давление мм.р.ст."))
self.l_temp_3.setText(_translate("Form", "скорость ветра"))
self.btn_more.setText(_translate("Form", "_____"))
self.l_day.setText(_translate("Form", "воскресеьне"))
ПРОДОЛЖЕНИЕ ОТВЕТА.
Приложение
не запускается при отсутствии подключения к интернету.Показывает ошибку
TypeError: 'bool' object is not subscriptable
UPDATE
main.py
import sys
import datetime
from PyQt5 import uic, QtCore, QtTest, QtWidgets, QtGui
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QThread, pyqtSignal
import weather
from weather import DAYS
# +++ pyuic5 root.ui -o root_ui.py -x
from root_ui import Ui_Form
#два класса с числами Фобаначе , для правного визуала
H_show = [
155, 156, 157, 158,
160, 168, 181, 202,
236, 291, 380, 400,
440, 500, 535,
]
H_hide = [
155, 156, 157, 158,
160, 168, 181, 202,
236, 291, 380, 400,
440, 500, 535,
]
class WeatherData(QThread):
req = weather.today()
mySignal = pyqtSignal()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
if req: # !!!
temp = req['temp']
feels = req['feels']
pres = req['pressure']
speed = str(req['wind']['speed'])
city = req['city']
type = req['dis']
week = weather.week()
flag = True
else:
flag = False
temp = ''
feels = None
pres = None
speed = ''
city = None
type = None
week = []
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def __init__(self):
super().__init__()
def run(self):
# ! while True:
while self.flag: # !!!
req = weather.today()
req_week = weather.week()
if req_week and req:
self.week = req_week
self.temp = req['temp']
self.feels = req['feels']
self.pres = req['pressure']
self.speed = str(req['wind']['speed'])
self.city = req['city']
self.type = req['dis']
else:
self.mySignal.emit()
self.msleep(1000 * 7) # 1000 * 60 * 30 = 1800сек = 30мин
print(f'def run(self): работает.')
self.mySignal.emit() # !!!
class MyRoot(QWidget, Ui_Form):
def __init__(self):
super().__init__()
self.setupUi(self)
class App(QWidget):
show_more = True
def __init__(self):
super().__init__()
self.weather = WeatherData()
self.weather.mySignal.connect(self._error)
self.weather.start()
self.set()
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
if self.weather.flag: # !!!
self.setData()
self.setMore()
self.timer = QtCore.QTimer() # !!!
self.timer.timeout.connect(self.updateTime) # !!!
self.timer.setInterval(3000)
QtCore.QTimer.singleShot(1000, self.timer.start)
def updateTime(self):
if self.weather.flag:
return
req = weather.today()
if req:
self.weather.temp = req['temp']
self.weather.feels = req['feels']
self.weather.pres = req['pressure']
self.weather.speed = str(req['wind']['speed'])
self.weather.city = req['city']
self.weather.type = req['dis']
self.weather.week = weather.week()
self.set()
self.setData()
self.setMore()
self.weather.flag = True
self.weather.start()
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
def _error(self):
print(f'\n"Проверьте доступ в интернет !!!"\n')
self.weather.flag = False # !!!
def set(self):
# self.w_root = uic.loadUi('root.ui')
self.w_root = MyRoot()
self.w_root.show()
self.w_root.btn_more.clicked.connect(self.setHeight)
#устанавливаем значение на сегодня
def setData(self):
self.w_root.l_temp.setText(str(self.weather.temp) + '°C')
self.w_root.l_fell.setText(self.weather.feels)
self.w_root.l_pres.setText(self.weather.pres)
self.w_root.l_wind.setText(self.weather.speed + 'м/с')
self.w_root.l_city.setText(self.weather.city)
self.w_root.l_type.setText(self.weather.type)
# иконка погоды
px_logo = QPixmap(f'Ok.png')
self.w_root.l_logo.setPixmap(px_logo)
# день недели
today = DAYS[datetime.datetime.today().weekday()]
self.w_root.l_day.setText(today['title'])
color = today['color']
self.w_root.l_day.setStyleSheet(f'color:{color}')
def setHeight(self):
if self.w_root.height() >= 300:
self.show_more = False
if self.show_more:
for i in H_hide:
if self.w_root.height() > i:
continue
self.w_root.resize(444, i)
self.w_root.btn_more.move(0, i-26)
self.w_root.l_day.move(8,i-18)
QtWidgets.QApplication.processEvents()
self.show_more = False
else:
for i in reversed(H_show):
self.w_root.resize(444, i)
self.w_root.btn_more.move(0, i-26)
self.w_root.l_day.move(8,i-18)
QtWidgets.QApplication.processEvents()
self.show_more = True
App.show_more = self.show_more
def setMore(self):
for i in self.weather.week:
w_day = uic.loadUi('day.ui')
w_day.setObjectName('w_day_' + str(i['num']))
w_day.l_title.setText(i['title'])
w_day.l_temp.setText(str(round(i['temp'])) + '°C')
w_day.l_type.setText(i['type'])
w_day.l_title.setStyleSheet(
'color: ' + i['color'] + '; background-color: none; border: none')
if i['active']:
w_day.setStyleSheet('border: 1px solid' + i['color'])
else:
w_day.setStyleSheet('border: none')
self.w_root.box.addWidget(w_day)
self.w_root.box.addStretch()
if __name__ == '__main__':
app = QtWidgets.QApplication([])
ex = App()
ex.show
sys.exit(app.exec_())



