Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 29, 2018 17:36:12

DarkNocturne
Зарегистрирован: 2018-08-29
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

Помогите справиться с QSpinBox'ом !
Надо при нажатии на кнопку вытаскивать значение QSpinBox'a для дальнейших вычислений внутри другой функции (не относящийся к функции нажатия на кнопку) - но как только я пытаюсь вытащить числа из qspinbox'а - приложение крашится. Если хэштегами отрубить функцию получения значений из qspinbox'a и на вывод поставить просто

 self.datelbltest.setText('value: ' + result)
, то результат получается корректным и ничего не крашится

Вот код:
 import sys, datetime
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QMessageBox, QApplication, QCalendarWidget, QLabel, QSpinBox, QPushButton, QMainWindow
from PyQt5.QtGui import QIcon, QFont
from PyQt5.QtCore import QDate, Qt, pyqtSignal, QObject
datenum = 0
result = 0
num_char = 0
num_expr = 0
num_fate = 0
num_bscyear = 0
num_fnyear = 0
num_expryear = 0
summ_bday = 0
summ_bdmonth = 0
summ_bdyear = 0
summ_ftyear = 0
summ_ftyearlast = 0
class Communicate(QObject):
    closeApp = pyqtSignal()
class mainframe(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        global datenum
        self.c = Communicate()
        self.c.closeApp.connect(self.close)
        btnExit = QPushButton("Выход", self)
        btnExit.move(20, 480)
        btnExit.resize(120,40)
        btnExit.setFont(QFont("Times New Roman", 14, QFont.Bold))
        btnExit.clicked.connect(self.exitEvent)
        self.datelbl1 = QLabel(self)
        self.datelbl1.setText("Дата рождения")
        self.datelbl1.move(95, 15)
        self.datelbl1.setFont(QFont("Times New Roman", 12, QFont.Bold))
        self.datelbl1.adjustSize()
        self.datelbl2 = QLabel(self)
        self.datelbl2.setText("Год прогноза")
        self.datelbl2.move(292, 15)
        self.datelbl2.setFont(QFont("Times New Roman", 12, QFont.Bold))
        self.datelbl2.adjustSize()
        self.datelbltest = QLabel(self)
        self.datelbltest.setText("date test")
        self.datelbltest.move(20, 300)
        self.datelbltest.adjustSize()
        cal = QCalendarWidget(self)
        cal.setGridVisible(False)
        cal.move(20, 40)
        cal.setVerticalHeaderFormat(0)
        cal.clicked[QDate].connect(self.showDate)
        self.lbl = QLabel(self)
        date = cal.selectedDate()
        self.lbl.setText(date.toString(Qt.ISODate))
        self.lbl.move(110, 230)
        qsb = QSpinBox(self)
        qsb.move(300, 40)
        qsb.resize(75,25)
        qsb.setAlignment(Qt.AlignCenter)
        qsb.setMinimum(1900)
        qsb.setMaximum(2100)
        qsb.setFont(QFont("Times New Roman", 14, QFont.Bold))
        btn1 = QPushButton("Рассчитать матрицу", self)
        btn1.move(18, 255)
        btn1.resize(360,40)
        btn1.setFont(QFont("Times New Roman", 14, QFont.Bold))
        btn1.clicked.connect(self.setupmatrix)
        self.setFixedSize(960, 540)
        self.center()
        self.setWindowIcon(QIcon('icon.png'))
        self.setWindowTitle('|Event Matrix|PC edition|')
        datenum = date.toString(Qt.ISODate)
        self.show()
    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Выход из приложения',
            "Вы уверены, что хотите выйти?", QMessageBox.Yes |
            QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
    def showDate(self, date):
        global datenum
        self.lbl.setText(date.toString(Qt.ISODate))
        datenum = date.toString(Qt.ISODate)
    def setupmatrix(self):
        global summ_ftyearlast
        global result
        
        mainframe.calculate(self)
        self.datelbltest.setText('value: ' + summ_ftyearlast)
        self.datelbltest.adjustSize()
    def exitEvent(self, event):
        self.c.closeApp.emit()
    @staticmethod
    def calculate(self):
        
        global result
        global datenum
        global num_char
        global num_expr
        global num_fate
        global summ_ftyear
        global summ_ftyearlast
        
        num0 = int(datenum[0])
        num1 = int(datenum[1])
        num2 = int(datenum[2])
        num3 = int(datenum[3])
        result = str(num0+num1+num2+num3)
        if len(result) >= 2:
            resnum1 = int(result[0])
            resnum2 = int(result[1])
            result = str(resnum1+resnum2)
        ftyeartext = self.qsb.value()
        last1 = int(ftyeartext[2])
        last2 = int(ftyeartext[3])
        summ_ftyearlast = str(last1+last2)
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = mainframe()
    sys.exit(app.exec_())

Офлайн

#2 Авг. 30, 2018 00:55:51

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9716
Репутация: +  842  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

DarkNocturne
 qsb = QSpinBox(self)
 self.qsb = QSpinBox(self)



Офлайн

#3 Авг. 30, 2018 08:16:45

DarkNocturne
Зарегистрирован: 2018-08-29
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

py.user.next
  self.qsb = QSpinBox(self)
Не помогло

Поменял код на:
        self.qsb = QSpinBox(self)
        self.qsb.move(300, 40)
        self.qsb.resize(75,25)
        self.qsb.setAlignment(Qt.AlignCenter)
        self.qsb.setMinimum(1900)
        self.qsb.setMaximum(2100)
        self.qsb.setFont(QFont("Times New Roman", 14, QFont.Bold))

Итог = приложение также крашится при нажатии на кнопку

Отредактировано DarkNocturne (Авг. 30, 2018 08:17:49)

Офлайн

#4 Авг. 30, 2018 09:43:51

DarkNocturne
Зарегистрирован: 2018-08-29
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

Все, нашел как решить проблему (пришлось добавить костыль)
Тут припаял еще глобальную переменную от спинбокса

    @staticmethod
    def calculate(self):
        
        global result
        global datenum
        global spinbox
        global num_char
        global num_expr
        global num_fate
        global summ_ftyear
        global summ_ftyearlast
        
        num0 = int(datenum[0])
        num1 = int(datenum[1])
        num2 = int(datenum[2])
        num3 = int(datenum[3])
        result = str(num0+num1+num2+num3)
        if len(result) >= 2:
            resnum1 = int(result[0])
            resnum2 = int(result[1])
            result = str(resnum1+resnum2)
        last1 = int(spinbox[2])
        last2 = int(spinbox[3])
        summ_ftyearlast = str(last1+last2)

Прокачал сам спинбокс для подачи сигналов при изменении
        self.qsb = QSpinBox(self)
        self.qsb.move(300, 40)
        self.qsb.resize(75,25)
        self.qsb.setAlignment(Qt.AlignCenter)
        self.qsb.setMinimum(1900)
        self.qsb.setMaximum(2100)
        self.qsb.setFont(QFont("Times New Roman", 14, QFont.Bold))
        self.qsb.valueChanged.connect(self.spinboxChanged)

И теперь при любых изменениях приходится еще в одну переменную загонять значения спинбокса
    def spinboxChanged(self):
        global spinbox
        spinbox = str(self.qsb.value())

Отредактировано DarkNocturne (Авг. 30, 2018 09:44:44)

Офлайн

#5 Авг. 30, 2018 10:32:23

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9716
Репутация: +  842  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

Глобальных переменных не должно быть вообще в программе. Используй return или аргумент в виде списка, в который добавляются результаты.

И ты ещё не понимаешь, что такое @staticmethod, этот декоратор тебе вообще не нужен.



Отредактировано py.user.next (Авг. 30, 2018 10:33:11)

Офлайн

#6 Авг. 30, 2018 11:52:46

DarkNocturne
Зарегистрирован: 2018-08-29
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

py.user.next
Глобальных переменных не должно быть вообще в программе. Используй return или аргумент в виде списка, в который добавляются результаты.И ты ещё не понимаешь, что такое @staticmethod, этот декоратор тебе вообще не нужен.

Чем тебе глобальные переменные не угодили?
Через return я хз как работать еще, так что пока и так сойдет…

а декоратор этот нужен, чтобы функцию нормально вызывать откуда угодно (если я не прав - то я хз, в инете про использование функций прочитал - у меня без этого крашилось приложение, а когда прописал этот декоратор - все заработало )

Офлайн

#7 Авг. 30, 2018 13:56:46

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9716
Репутация: +  842  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

DarkNocturne
Чем тебе глобальные переменные не угодили?
Они вредят программе. Вопрос глупый, даже школьники знают, почему глобальные переменные не используются. Глобальная переменная может быть изменена из любого места в программе, поэтому ты в любом месте программы не знаешь, какое именно значение находится в глобальной переменной в данный момент.

DarkNocturne
Через return я хз как работать еще, так что пока и так сойдет…
Программа будет расти в размере и ты не сможешь всегда помнить, где и какая переменная меняется. Потом просто всё будет сводиться к работе с фрагментом программы и все влияния на все переменные фрагмента должны будут находиться под рукой. А с глобальными переменными ты даже не можешь сказать, какая часть программы запишет в них значения последней. Программу надо делить на части и части эти изолировать друг от друга, соединяя через тонкие, определённые в одном месте каналы (аргументы функций и возвращаемые значения функций). Таким образом каждая часть становится независимой от остальной программы и ты можешь её отлаживать отдельно как маленький кусок. При этом все изменения в маленьком куске программы никак не влияют на остальные части программы.

DarkNocturne
а декоратор этот нужен, чтобы функцию нормально вызывать откуда угодно
Декоратор нужно убрать, а вместо глобальных переменных использовать атрибуты из self. Когда используешь этот декоратор, то нужно self убирать, потому что такой метод (статический) используется без участия экземпляра.
  
>>> class A:
...     @staticmethod
...     def f():
...         return 1
... 
>>> A.f()
1
>>> 



Отредактировано py.user.next (Авг. 30, 2018 14:01:47)

Офлайн

#8 Авг. 30, 2018 14:17:28

DarkNocturne
Зарегистрирован: 2018-08-29
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

py.user.next
Они вредят программе. Вопрос глупый, даже школьники знают, почему глобальные переменные не используются. Глобальная переменная может быть изменена из любого места в программе, поэтому ты в любом месте программы не знаешь, какое именно значение находится в глобальной переменной в данный момент.
Я буквально пару дней сижу на питоне и еще мало чего понимаю - разбраться с ним мне помогает яндекс (гугль неудобный для меня), а цель непростая - нужно сделать программу, которая будет проводить математические вычисления на основе различных дат (суммы чисел года, месяца, дня и т.д и т.п), но вот пока что застрял на уровне интерфейса и взаимодействия элементов

py.user.next
Программа будет расти в размере и ты не сможешь всегда помнить, где и какая переменная меняется. Потом просто всё будет сводиться к работе с фрагментом программы и все влияния на все переменные фрагмента должны будут находиться под рукой. А с глобальными переменными ты даже не можешь сказать, какая часть программы запишет в них значения последней. Программу надо делить на части и части эти изолировать друг от друга, соединяя через тонкие, определённые в одном месте каналы (аргументы функций и возвращаемые значения функций). Таким образом каждая часть становится независимой от остальной программы и ты можешь её отлаживать отдельно как маленький кусок. При этом все изменения в маленьком куске программы никак не влияют на остальные части программы.

Ну программа не будет расти в размере - у меня уже есть готовая программа на андроиде и мне надо просто перенести ее на пекарню с новым интерфейсом (но я не знаю ни одного ЯП), так что я знаю точно как все должно работать (я делал ту прогу через проприетарный игровой движок Construct 2) и поэтому не думаю, что я запутаюсь или не смогу отследить переменные (которые я уже обозначил и прописал), также учитывая, что процесс просчета достаточно линейный - отслеживание всех переменных в цепочке не проблема, а также я пока обхожусь без return'ов вполне успешно и не хочу пока тратить время на них, если не возникнет острая необходимость

py.user.next
Декоратор нужно убрать, а вместо глобальных переменных использовать атрибуты из self. Когда используешь этот декоратор, то нужно self убирать, потому что такой метод (статический) используется без участия экземпляра.

Спасибо, я уже убрал и все вроде работает (прога не крашится) - странно, что раньше она без него крашилась

P.S. также воюю с QCalendarWidget, чтобы достать оттуда значения дня недели(ну типа пятница = 5)

Отредактировано DarkNocturne (Авг. 30, 2018 14:26:25)

Офлайн

#9 Авг. 31, 2018 03:48:08

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9716
Репутация: +  842  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

DarkNocturne
Я буквально пару дней сижу на питоне и еще мало чего понимаю
Питон - это один из языков программирования. Но программирование имеет собственную теорию, не связанную ни с одним языком. И вот в этой теории есть определённый опыт, накопившийся со временем. Многие программисты делали многие программы (тысячи программистов и тысячи программ) и пришли к одному и тому же выводу насчёт глобальных переменных. В литературе по питону тебе про это писать не будут, так как это и так известно из общей теории программирования. Поэтому ты можешь и не узнать этих вещей, пока фокусируешься только на питоне и литературе по нему.

DarkNocturne
разбраться с ним мне помогает яндекс (гугль неудобный для меня)
Google и Yandex - это разные системы, имеющие свои плюсы и минусы. Yandex хорошо ищет русскоязычное и сортирует результаты поиска по популярности (часто популярность материалов эквивалентна качеству), в то время как Google имеет средства для более точного поиска, когда ты уже точно знаешь, что нужно найти. Поисковый язык Google позволяет искать по кускам ссылок, по заголовкам внутри страниц по типам файлов.
http://www.googleguide.com/advanced_operators_reference.html

Есть ещё https://www.duckduckgo.com (сокращённо можно набирать ddg.gg ), на котором есть бэнги (встроенные команды через восклицательный знак).

Там можно ввести например
!gt dog
и он тебе сразу откроет переводчик Google с этим словом.

Там можно ввести например
!w dog
и он тебе сразу откроет Википедию с этим словом.

Там можно ввести например
!wolfram sin(pi/2)
и он тебе сразу откроет Вольфрам с этим выражением.

Там можно ввести например
!pip crypto
и он тебе сразу откроет питоновскую базу с этим модулем.

Там можно ввести например
!pep 20
и он тебе сразу откроет питоновский PEP с этим номером.

Есть и встроенные фичи (не бэнги, а просто команды, называется “instant answers”)

Там можно ввести например
md5 text
и он тебе сразу покажет сверху хеш этой строки - 1cb251ec0d568de6a929b520c4aed8d1.

Там можно ввести например
ascii code cheat sheet
и он тебе сразу покажет аски-коды символов.

DarkNocturne
но вот пока что застрял на уровне интерфейса и взаимодействия элементов
Интерфейс программы и содержимое программы - это независимые части программы. Один интерфейс можно подключать к разному содержимому, а одно содержимое можно подключать к разным интерфейсам. Поэтому надо писать заранее изолированно. Как в компьютере - все детали изолированы друг от друга, поэтому ты можешь комп купить в одном магазине, жёсткий диск к нему купить в другом магазине, а кулер купить в третьем магазине. И всё будет работать, когда соединишь, как будто в одном магазине купил всё.
Также изолированность позволяет писать любую часть программы в любое время. Ты можешь писать ядро программы и отлаживать его, не имея интерфейса, и писать интерфейс и отлаживать его, не имея ядра программы. Вместо отсутствующих частей можно делать заглушки или псевдочасти. Заглушка просто возвращает ответ и ничего больше не делает, тогда как псевдочасть может изображать какую-то работу якобы готовой части, хотя при этом её не нужно писать со всеми подробностями. Заглушка называется stub, а псевдочасть называется mock.

DarkNocturne
Ну программа не будет расти в размере
Когда она вырастет или даже не вырастет, а поменяется десять раз, ты на себе ощутишь влияние глобальных переменных, но уже будет поздно что-то менять, так как вся программа будет пронизана этими глобальными переменными. Когда тебе в сотый раз нужно будет полностью перечитывать одну и ту же программу и многие места перечитывать, которые ты уже перечитывал, ты поймёшь, что время утекло и на разработку ничего не осталось. Поэтому, соблюдая правила, ты экономишь собственное время в будущем. А когда ты уже нормально программируешь, то программу на 10000 строк ты уже физически не сможешь перечитывать, потому что только на прочтение будет уходить неделя, если не больше. И у тебя всё время будет всплывать вопрос в голове “зачем я это снова читаю? я же уже читал это десять раз”. Так будет происходить после каждого малейшего изменения в программе - где-то баг обнаружился и его надо исправить, где-то фича срочно понадобилась и её надо быстро добавить. Это неизбежные вещи, про которые ты пока что не в курсе.


DarkNocturne
и поэтому не думаю, что я запутаюсь или не смогу отследить переменные
Достаточно иметь две похожие программы, чтобы начать забывать, что и где было в первой программе. Даже в пределах одной программы можно словить такой эффект. Достаточно, чтобы у неё было две-три версии (старая, поновее и самая новая). Как только нарушишь обратную совместимость - удалишь то, что было в программе, как ненужное, - так сразу начнутся вопросы к этим различиям и глобальным переменным, с ними связанным. То есть тебе надо будет их и держать в одной версии, и удалять их из другой версии. И всё это надо будет держать в голове одновременно.

DarkNocturne
P.S. также воюю с QCalendarWidget, чтобы достать оттуда значения дня недели
Да, можно и просто перейти на другое задание, чтобы забыть содержимое того задания, которое делал до этого, дня за три.

Так что изучай правила общепринятые, соблюдай их без вопросов. Когда придёт время, ты будешь благодарен, что тебе посоветовали начать с них, а не терять время на набивание глупых шишек.



Отредактировано py.user.next (Авг. 31, 2018 04:11:03)

Офлайн

#10 Сен. 10, 2018 09:55:49

DarkNocturne
Зарегистрирован: 2018-08-29
Сообщения: 16
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQT5 Python 3.6 QSpinBox

py.user.next
Так что изучай правила общепринятые, соблюдай их без вопросов. Когда придёт время, ты будешь благодарен, что тебе посоветовали начать с них, а не терять время на набивание глупых шишек.

Спасибо я тебе не скажу ибо программа уже почти готова и никаких набиваний шишек из-за глобальных переменных не случилось - все работает как часы и без всяких return - к изучению общепринятых правил я буду приступать только, когда это действительно потребуется, но если уж и серъезно изучать язык, то я взялся бы сначала за Java, а потом за Kotlin - питон мне был нужен как максимально простой и “читаемый” язык, чтобы “на коленке” собрать ПК аналог уже готовой мобильной программы вот и все…

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version