Faun_
Пишу проги для МикроКонтроллеров(МК), увлекаюсь этим чуть ни с детства, при этом высокуровневку пытался, не далась. Видимо мозг так заточен…
Ассемблер может выучить любой школьник, но чтобы писать программу на ассемблере, нужно представлять устройство механизма, для которого пишешь программу. Вот это сложность “ассемблера” - разбираться в механизме, для которого пишешь на ассемблере. Поэтому ассемблер считают сложным, хотя сложен не ассемблер, ассемблер прост. Кстати, на C та же самая ситуация - его считают сложным, в то время как сложен не он сам, а то, для чего его используют и то, как его используют. Когда пишешь на C, надо его весь в голове держать очень точно и отчётливо себе представлять, во что этот код (каждая строка) скомпилируется. Если этого не делать, можно допустить ошибку из-за пробелов в знании самого языка и эта ошибка проявится только в работе программы уже гораздо позже релиза этой программы.
Ну и, если рассматривать механизмы, для которых пишут на ассемблере, они тоже бывают простые и сложные. И писать на ассемблере для простого механизма ничего сложного из себя не представляет. Часто это различие используют, чтобы нанести такой флёр таинственности и высокого мастерства, когда на самом деле там ничего мастерского нет.
Вот поэтому, когда такие ассемблерщики попадают в мир реального программирования - когда надо сделать программу сложнее чем 2 + 2 (строк на 1000 или на 5000), - они нифига не могут не только сделать, но и разобраться в, казалось бы, простом. Проблемы начинаются на стадии проектирования, они не умеют проектировать программы сложнее десятка процедур.
Так что сбрасывай самомнение на ноль. Скажи себе, что ничего не знаешь и не умеешь, и начинай сначала всё изучать, классически. Если ты что-то знаешь, оно подцепится и ты быстро это пройдёшь заново. Если же ты чего-то не знаешь, то ты не станешь это бросать - уходить от этого, якобы ты это знаешь и так, но время не хочешь тратить, - а станешь изучать, чтобы узнать впервые.
Изучил ли ты процедурную парадигму программирования?
Изучил ли ты структурную парадигму программирования?
Без этого нельзя переходить к парадигме ООП, потому что парадигма объектно-ориентированного программирования не замена этим двум парадигмам, а дополнение к ним. И ООП не научит тебя разрабатывать программы, а лишь даст дополнительные плюсы и плюшки, упрощая твою разработку программ, уже спроектированных по классическим методикам.
Faun_
class MyWin(QtWidgets.QMainWindow): ## -1- ## QMainWindow это класс, типа контейнер в котором лежит ВСЁ, для того чтобы рисовать окна PyQt.. Вопрос, почему эта строчка здесь, а не в блоке, который собрал Qt-designer... Эта строчка всегда одна и та-же(в любых ситуациях), или это параметр от чего-та зависящий?
def __init__(self, parent=None): ## -2- ## Что такое "parent=None"?. Это я передаю какую-то переменную со значением "None".. Но куда, что это такое.
QtWidgets.QWidget.__init__(self, parent) ## -3- ## Читал разные уроки, там сказано "__init__" это какой-та конструктор, просто пишите его ВО ВСЕХ прогах, и только единственный раз,.. а понимать вам не обязательно. И вот он уже второй раз в единственной проге, и появился вопрос, так что-же это, должна ведь быть причина , что он использован дважды!
self.ui = Ui_MainWindow() ## -4- ## Что такое "*.ui"?. Да, вроде называется "метод", но в документации это используется только как аббривиатура "User Iterfeys".. Но ведь она для чего-та нужна? Как понять, что это такое, чтобы я знал, где это писать...
self.ui.setupUi(self)
1) Почему QMainWindow и в скрипте, и в форме из Qt Designer'а
Форма в Qt Designer'е - это не вся программа, а просто кусок программы. Ты делаешь куски программы в виде разных форм и подключаешь каждую форму к программе. У программы есть главное окно, но оно имеет общий вид и чистое содержимое, поэтому ты берёшь созданную форму и копируешь все настройки и содержимое из неё в главное окно. Таким образом главное окно приобретает вид твоей формы и содержимое этой формы. А потом ты можешь к этим скопированным настройкам добавлять ещё настройки. Так ты можешь одну форму использовать для настройки разных окон своей программы, но при этом в разных окнах иметь ещё и какие-то индивидуальные настройки этих окон.
2) Что такое parent.
Это родительское окно (или виджет). Нужна эта штука, чтобы освобождать ресурсы. Когда окно закрывается, оно освобождает свои ресурсы и заходит в каждый дочерний элемент и закрывает его, а тот в свою очередь так же освобождает свои ресурсы и заходит в свои дочерние элементы и вызывает их закрытие. У тебя получается дерево виджетов, в котором завершение родительских виджетов приводит к завершению дочерних виджетов. Так ты, закрыв главное окно, вызываешь цепочку закрытий (правильных закрытий) всех его дочерних окон, кнопок, меток и других элементов.
3) Что такое __init__ и почему он вызывается.
__init__() - это служебный метод. То есть это значит, что вызывать его напрямую в коде не требуется. После создания объекта этот метод сразу вызывается сам собой и заполняет объект первичными значениями, которые программист может написать в коде. Но мы имеем наследование - есть родительский класс общего вида и дочерний класс, который от него унаследован. В них обоих есть __init__() и унаследованный класс заменяет своим __init__()'ом родительский __init__(). __init__()'ы родительского и дочернего класса могут полностью различаться как по содержимому, так и по аргументам. Если ты напишешь в __init__()'е дочернего класса заполнение объекта какими-то значениями, то тот __init__(), который находится в родительском классе, не выполнится, так как весь этот родительский __init__() заменён дочерним __init__()'ом. При создании объекта дочернего класса сам собой у этого объекта вызывается только дочерний __init__(), а родителский __init__() не вызывается, так как он бы вызвался, если бы ты объект родительского класса создал. Поэтому, если у тебя в родительском классе записано, что __init__() должен проставить такие-то значения в объекте этого класса, нужно соблюсти это условие. Но так как объект дочернего класса вызывает собственный __init__() и проставляет собственные значения, то внутри этого дочернего __init__()'а сначала нужно вызвать родительский __init__() с правильными для родительского __init__()'а значениями и только после этого выполнять установки дочерних значений.
В общем, дочерний __init__() полностью заменяет родительский __init__(), но родительский __init__() писался для чего-то, поэтому его нужно вызвать до всех операций в дочернем __init__()'е, чтобы он сделал своё дело.
4) Что такое ui, которое фигурирует в коде.
UI - User Interface (пользовательский интерфейс или интерфейс для пользователя). В названии класса этот префикс символизирует о том, что это только внешний вид окна, а не само окно со всей его работой, запрограммированными процессами там и так далее. Мы можем взять окно, в котором не только установлен внешний вид, но и которое связано как-то с другими окнами и частями программы, которое как-то работает уже. Вот такое окно будет называеться Window, например. Но внешний вид этого окна (расположение элементов на нём, кнопки слева или справа или внизу) будет называться UiWindow. И к окну Window будет подключаться вид окна UiWindow, чтобы придать окну определённый внешний вид. А окно Window уже можно будет подключать в каком-то месте программы, чтобы работать уже с готовым, полноценно работающим окном, которое и выглядит определённым образом, и работает по определённым правилам, имеет связи какие-то с другими элементами программы и что-то делает.
В названии переменной ui также означает, что там хранится объект интерфейса пользователя. UiWindow - это класс интерфейса пользователя, а ui - это объект этого класса - класса интерфейса пользователя.
В общем, чтобы изучать PyQt, надо сначала освоить парадигму ООП. PyQt полностью выполнено в этой парадигме и соблюдает её правила во всех своих частях. Питон же сам соблюдает парадигму ООП не полностью и имеет ещё некоторые хаки, которые выглядят как ООП, но по сути устроены по-другому. Так что без понимания парадигмы ООП тебе будет сложно понимать логику устройства PyQT, а также будет сложно понимать сам питон в некоторых моментах.
tags: assembler programers