Форум программистов, компьютерный форум, киберфорум
iamvic
Войти
Регистрация
Восстановить пароль
Путевые заметки в процессе познания Python и PyQt/PySide.
Помни - только тег CODE не портит код добавлением пробела в начало пустой строки.
Оценить эту запись

К вопросу о соразмерности виджетов разрешению экрана...

Запись от iamvic размещена 04.03.2024 в 17:02
Обновил(-а) iamvic 29.03.2024 в 20:53 (исправление тега)
Метки pyqt5, python 3, qt designer

Поучаствовал тут в разборках интересного казуса, как раз подходящего для Памятки. Суть-то в том, что версии HDMI весьма различны и в ряде случаев высоконасыщенный элементами управления виджет, разработанный под последнее слово техники, может просто не влезть на экран в случае замены штатного монитора на старенький резервный с гораздо меньшим разрешением.

Оказалось, что можно попробовать использовать скроллинг для таких случаев
Нажмите на изображение для увеличения
Название: scroll_probe_tz.jpg
Просмотров: 30
Размер:	17.2 Кб
ID:	8582
а лучше так:
Нажмите на изображение для увеличения
Название: scroll_probe_result.jpg
Просмотров: 13
Размер:	30.4 Кб
ID:	8595

1. программерское решение

scroll_probe.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Scroll Probe
import sys
from PyQt5 import QtWidgets
 
class Scroll_probe(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Scroll_probe, self).__init__(parent)
 
        text_edt = QtWidgets.QPlainTextEdit()
        push_btn_1 = QtWidgets.QPushButton("Push Button 1")
        push_btn_2 = QtWidgets.QPushButton("Push Button 2")
        push_btn_3 = QtWidgets.QPushButton("Push Button 3")
        push_btn_4 = QtWidgets.QPushButton("Push Button 4")
 
        v_layout = QtWidgets.QVBoxLayout()
        v_layout.addWidget(push_btn_1)
        v_layout.addWidget(push_btn_2)
        v_layout.addWidget(push_btn_3)
        v_layout.addStretch(1)
        v_layout.addWidget(push_btn_4)
 
        h_layout = QtWidgets.QHBoxLayout()
        h_layout.addWidget(text_edt)
        h_layout.addLayout(v_layout)
 
        scr_content = QtWidgets.QWidget()
 
        scr_area = QtWidgets.QScrollArea(self)
        scr_area.setWidgetResizable(True)
        scr_area.setWidget(scr_content)
 
        v_area = QtWidgets.QVBoxLayout(scr_content)
        v_area.addLayout(h_layout)
 
        h_area = QtWidgets.QHBoxLayout()
        h_area.addWidget(scr_area)
 
        self.setLayout(h_area)
 
 
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
 
    mwin = Scroll_probe()
    mwin.show()
    sys.exit(app.exec_())

2. дизайнерское решение

scroll_probe_ui.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Scroll Probe with UI file
import sys
from PyQt5 import (
    QtWidgets,
    uic
    )
 
class Scroll_probe(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Scroll_probe, self).__init__(parent)
        uic.loadUi('scroll_probe.ui', self)
 
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
 
    mwin = Scroll_probe()
    mwin.show()
    sys.exit(app.exec_())

scroll_probe.ui
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>406</width>
    <height>295</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout_2">
   <item>
    <widget class="QScrollArea" name="scrollArea">
     <property name="widgetResizable">
      <bool>true</bool>
     </property>
     <widget class="QWidget" name="scrollAreaWidgetContents">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>390</width>
        <height>279</height>
       </rect>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QPlainTextEdit" name="plainTextEdit"/>
         </item>
         <item>
          <layout class="QVBoxLayout" name="verticalLayout">
           <item>
            <widget class="QPushButton" name="pushButton">
             <property name="text">
              <string>Push Button 1</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QPushButton" name="pushButton_2">
             <property name="text">
              <string>Push Button 2</string>
             </property>
            </widget>
           </item>
           <item>
            <widget class="QPushButton" name="pushButton_3">
             <property name="text">
              <string>Push Button 3</string>
             </property>
            </widget>
           </item>
           <item>
            <spacer name="verticalSpacer">
             <property name="orientation">
              <enum>Qt::Vertical</enum>
             </property>
             <property name="sizeHint" stdset="0">
              <size>
               <width>20</width>
               <height>40</height>
              </size>
             </property>
            </spacer>
           </item>
           <item>
            <widget class="QPushButton" name="pushButton_4">
             <property name="text">
              <string>Push Button 4</string>
             </property>
            </widget>
           </item>
          </layout>
         </item>
        </layout>
       </item>
      </layout>
     </widget>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

Обновление от 17.03.2024

Есть тут одна заноза в качестве повода для размышлений... В документации-то QScrollArea Class сказано следующее:
Цитата:
Обратите внимание: перед вызовом этой функции необходимо добавить в виджет макет (add the layout of widget); если вы добавите его позже, виджет не будет виден — независимо от того, когда вы методом show() покажете область прокрутки. В этом случае вы также не сможете показать этот виджет позже.
А тут почему-то этого не требуется - всё и так работает без всякого предварительного добавления макета. Например, можно перелицевать представленное решение так, чтобы было ясно видно, что никакие макеты в виджет (scr_content) не добавляются перед его установкой в свежесозданный экземпляр (scr_area) класса QScrollArea и это никак не мешает искомому виджету исполнять возложенные на него обязанности
scroll_probe.py
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Scroll Probe
import sys
from PyQt5 import QtWidgets
 
class Scroll_probe(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(Scroll_probe, self).__init__(parent)
 
        scr_content = QtWidgets.QWidget()
 
        scr_area = QtWidgets.QScrollArea(self)
        scr_area.setWidgetResizable(True)
        scr_area.setWidget(scr_content)
 
        text_edt = QtWidgets.QPlainTextEdit()
        push_btn_1 = QtWidgets.QPushButton("Push Button 1")
        push_btn_2 = QtWidgets.QPushButton("Push Button 2")
        push_btn_3 = QtWidgets.QPushButton("Push Button 3")
        push_btn_4 = QtWidgets.QPushButton("Push Button 4")
 
        v_layout = QtWidgets.QVBoxLayout()
        v_layout.addWidget(push_btn_1)
        v_layout.addWidget(push_btn_2)
        v_layout.addWidget(push_btn_3)
        v_layout.addStretch(1)
        v_layout.addWidget(push_btn_4)
 
        h_layout = QtWidgets.QHBoxLayout()
        h_layout.addWidget(text_edt)
        h_layout.addLayout(v_layout)
 
        v_area = QtWidgets.QVBoxLayout(scr_content)
        v_area.addLayout(h_layout)
 
        h_area = QtWidgets.QHBoxLayout()
        h_area.addWidget(scr_area)
 
        self.setLayout(h_area)
 
if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
 
    mwin = Scroll_probe()
    mwin.show()
    sys.exit(app.exec_())
Ну, не может же быть, что вышеприведённое замечание относится только к C++, а в документации Python его просто тупо отзеркалили, не проверяя на практике?
Размещено в Памятка
Показов 1046 Комментарии 9
Всего комментариев 9
Комментарии
  1. Старый комментарий
    Как говорится, за недолгим народилось и решение, соответствующее сказанному в документации:

    scroll_probe.py
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    #
    # Scroll Probe
    import sys
    from PyQt5 import QtWidgets
     
    class Scroll_probe(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Scroll_probe, self).__init__(parent)
     
            text_edt = QtWidgets.QPlainTextEdit()
            push_btn_1 = QtWidgets.QPushButton("Push Button 1")
            push_btn_2 = QtWidgets.QPushButton("Push Button 2")
            push_btn_3 = QtWidgets.QPushButton("Push Button 3")
            push_btn_4 = QtWidgets.QPushButton("Push Button 4")
     
            v_layout = QtWidgets.QVBoxLayout()
            v_layout.addWidget(push_btn_1)
            v_layout.addWidget(push_btn_2)
            v_layout.addWidget(push_btn_3)
            v_layout.addStretch(1)
            v_layout.addWidget(push_btn_4)
     
            h_layout = QtWidgets.QHBoxLayout()
            h_layout.addWidget(text_edt)
            h_layout.addLayout(v_layout)
     
            scr_area = QtWidgets.QScrollArea(self)
            scr_area.setWidgetResizable(True)
     
            v_area = QtWidgets.QVBoxLayout()
            v_area.addLayout(h_layout)
     
            h_area = QtWidgets.QHBoxLayout()
            h_area.addWidget(scr_area)
     
            scr_content = QtWidgets.QWidget()
            scr_content.setLayout(v_area)
     
            scr_area.setWidget(scr_content)
     
            self.setLayout(h_area)
     
     
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
     
        mwin = Scroll_probe()
        mwin.show()
        sys.exit(app.exec_())

    По крайней мере, теперь не требуется явное указание родителя в операторе
    Python
    1
    
            v_area = QtWidgets.QVBoxLayout()
    и можно быть уверенным, что родительские отношения будут выстроены в соответствии порядком применяемых макетов.

    В предыдущей-то версии было так
    Python
    1
    
            v_area = QtWidgets.QVBoxLayout(scr_content)
    и это несколько смущало, хотя и было подсмотрено в коде дизайнерского решения .
    Запись от iamvic размещена 19.03.2024 в 00:12 iamvic вне форума
  2. Старый комментарий
    А если глянуть под капот...

    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    #
    # Scroll Probe
    import sys
    from PyQt5 import QtWidgets
     
    def look_inside(n, ob):
        print('{!s}: id({!s}({!s})) = {!s}'
              ''.format(
                  n,
                  ob.objectName(),
                  ob.metaObject().className(),
                  hex(id(ob))
                  )
              )
     
    class Scroll_probe(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Scroll_probe, self).__init__(parent)
     
            text_edt = QtWidgets.QPlainTextEdit()
            push_btn_1 = QtWidgets.QPushButton("Push Button 1")
            push_btn_2 = QtWidgets.QPushButton("Push Button 2")
            push_btn_3 = QtWidgets.QPushButton("Push Button 3")
            push_btn_4 = QtWidgets.QPushButton("Push Button 4")
     
            v_layout = QtWidgets.QVBoxLayout()
            v_layout.addWidget(push_btn_1)
            v_layout.addWidget(push_btn_2)
            v_layout.addWidget(push_btn_3)
            v_layout.addStretch(1)
            v_layout.addWidget(push_btn_4)
     
            h_layout = QtWidgets.QHBoxLayout()
            h_layout.addWidget(text_edt)
            h_layout.addLayout(v_layout)
     
            scr_area = QtWidgets.QScrollArea(self)
            scr_area.setObjectName('scr_area')
            look_inside(0, scr_area)
            for x in scr_area.children():
                look_inside(1, x)
     
            scr_area.setWidgetResizable(True)
     
            v_area = QtWidgets.QVBoxLayout()
            v_area.setObjectName('v_area')
            v_area.addLayout(h_layout)
     
            h_area = QtWidgets.QHBoxLayout()
            h_area.addWidget(scr_area)
     
            scr_content = QtWidgets.QWidget()
            scr_content.setLayout(v_area)
     
            scr_area.setWidget(scr_content)
            look_inside(2, v_area)
     
            self.setLayout(h_area)
     
     
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
     
        mwin = Scroll_probe()
        mwin.show()
        sys.exit(app.exec_())
    Запись от iamvic размещена 19.03.2024 в 11:04 iamvic вне форума
  3. Старый комментарий
    ...то можно увидеть как мутабельные дети экземпляра класса QScrollArea деятельно принимают участие в создании должного GUI:
    Цитата:

    user@linux:~/qtprobe/scroll_probe> python3 scroll_probe.py
    0: id(scr_area(QScrollArea)) = 0x7fec13934ee8
    1: id(qt_scrollarea_viewport(QWidget)) = 0x7fec13934f78
    1: id(qt_scrollarea_hcontainer(QWidget)) = 0x7fec0c16c048
    1: id(qt_scrollarea_vcontainer(QWidget)) = 0x7fec0c16c0d8
    2: id(v_area(QVBoxLayout)) = 0x7fec13934f78
    Дополнение от 22.03.2024
    А схема родительских отношений выстроенного ими GUI весьма извилиста (для примера взято дизайнерское решение - имена всем объектам там уже назначены, что облегчает понимание):

    Bash
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    self == Form(Scroll_probe)
    |
    +---> scrollArea(QScrollArea)
          |
          +---> qt_scrollarea_viewport(QWidget) == scrollArea.viewport()
          |     |
          |     +---> scrollAreaWidgetContents(QWidget)
          |           |
          |           +---> verticalLayout_2(QVBoxLayout)
          |           |
          |           +---> plainTextEdit(QPlainTextEdit)
          |           |
          |           +---> pushButton(QPushButton)
          |           |
          |           +---> pushButton_2(QPushButton)
          |           |
          |           +---> pushButton_3(QPushButton)
          |           |
          |           +---> pushButton_4(QPushButton)
          |
          +---> qt_scrollarea_hcontainer(QWidget)
          |
          +---> qt_scrollarea_vcontainer(QWidget)
    Запись от iamvic размещена 19.03.2024 в 11:12 iamvic вне форума
    Обновил(-а) iamvic 22.03.2024 в 19:32 (Дополнение)
  4. Старый комментарий
    И соответствующий код стал выглядеть так:

    scroll_probe_ui.py
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    #
    # Scroll Probe with UI file
    import sys
    from PyQt5 import (
        QtCore,
        QtWidgets,
        uic
        )
     
    class Scroll_probe(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Scroll_probe, self).__init__(parent)
            uic.loadUi('scroll_probe.ui', self)
     
        @QtCore.pyqtSlot(name='on_pushButton_pressed')
        @QtCore.pyqtSlot(name='on_pushButton_2_pressed')
        @QtCore.pyqtSlot(name='on_pushButton_3_pressed')
        @QtCore.pyqtSlot(name='on_pushButton_4_pressed')
        def on_button_pressed(self):
            self.findChild(QtWidgets.QScrollArea).viewport(
                ).findChild(QtWidgets.QWidget, 'scrollAreaWidgetContents'
                ).findChild(QtWidgets.QPlainTextEdit, 'plainTextEdit'
                ).setPlainText('===> {!s} pressed'.format(
                    self.sender().text()
                    )
                )
     
     
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
     
        mwin = Scroll_probe()
        mwin.show()
        sys.exit(app.exec_())

    Приятно, что при загрузке scroll_probe.ui лихо отрабатывает
    Python
    1
    
    QtCore.QMetaObject.connectSlotsByName(Form)
    цепляя сигналы на соответствующие слоты. Зато к нужному экземпляру QPlainTextEdit приходится продираться через лабиринт для доказательства существования дерева родительских отношений. Хотя этого обычно и не требуется, достаточно использовать:
    Python
    1
    2
    3
    4
    5
    6
    
        def on_button_pressed(self):
            self.findChild(QtWidgets.QPlainTextEdit, 'plainTextEdit'
                ).setPlainText('===> {!s} pressed'.format(
                    self.sender().text()
                    )
                )
    Запись от iamvic размещена 22.03.2024 в 19:05 iamvic вне форума
    Обновил(-а) iamvic 26.03.2024 в 17:05
  5. Старый комментарий
    А программерский вариант может выглядеть так:
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    #
    # Scroll Probe
    import sys
    from PyQt5 import QtCore, QtWidgets
     
    class Scroll_probe(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Scroll_probe, self).__init__(parent)
     
            text_edt = QtWidgets.QPlainTextEdit()
            text_edt.setObjectName('text_edt')
            push_btn_1 = QtWidgets.QPushButton('Push Button 1')
            push_btn_1.setObjectName('push_btn_1')
            push_btn_2 = QtWidgets.QPushButton('Push Button 2')
            push_btn_2.setObjectName('push_btn_2')
            push_btn_3 = QtWidgets.QPushButton('Push Button 3')
            push_btn_3.setObjectName('push_btn_3')
            push_btn_4 = QtWidgets.QPushButton('Push Button 4')
            push_btn_4.setObjectName('push_btn_4')
     
            v_layout = QtWidgets.QVBoxLayout()
            v_layout.addWidget(push_btn_1)
            v_layout.addWidget(push_btn_2)
            v_layout.addWidget(push_btn_3)
            v_layout.addStretch(1)
            v_layout.addWidget(push_btn_4)
     
            h_layout = QtWidgets.QHBoxLayout()
            h_layout.addWidget(text_edt)
            h_layout.addLayout(v_layout)
     
            scr_area = QtWidgets.QScrollArea(self)
            scr_area.setObjectName('scr_area')
            scr_area.setWidgetResizable(True)
     
            v_area = QtWidgets.QVBoxLayout()
            v_area.addLayout(h_layout)
     
            h_area = QtWidgets.QHBoxLayout()
            h_area.addWidget(scr_area)
     
            scr_content = QtWidgets.QWidget()
            scr_content.setObjectName('scr_content')
            scr_content.setLayout(v_area)
     
            scr_area.setWidget(scr_content)
     
            self.setLayout(h_area)
     
            QtCore.QMetaObject.connectSlotsByName(self)
     
        @QtCore.pyqtSlot(name='on_push_btn_1_pressed')
        @QtCore.pyqtSlot(name='on_push_btn_2_pressed')
        @QtCore.pyqtSlot(name='on_push_btn_3_pressed')
        @QtCore.pyqtSlot(name='on_push_btn_4_pressed')
        def on_button_pressed(self):
            self.findChild(QtWidgets.QPlainTextEdit, 'text_edt'
                ).setPlainText('===> {!s} pressed'.format(
                    self.sender().text()
                    )
                )
     
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
     
        mwin = Scroll_probe()
        mwin.show()
        sys.exit(app.exec_())
    Запись от iamvic размещена 26.03.2024 в 17:10 iamvic вне форума
  6. Старый комментарий
    Ну и чтоб не забылось, ввиду непотребляемости , опишу как это делалось в Qt Designer:

    1. в диалоге New Form (Новая форма) выбрать Widget в templates/forms и нажать кнопку Создать (Create)
    2. перетащить на форму виджет Containers/Scroll Area
    3. растянуть его под разиер формы
    4. перетащить на Scroll Area четыре виджета Buttons/Push Button и один виджет Spacers/Vertical Spacer
    5. выстроить их в колонку в правой половине Scroll Area сверху вниз по порядку:
    Цитата:
    кнопка
    кнопка
    кнопка
    спейсер
    кнопка
    6. выбрать вышеуказанные виджеты для проведения групповой операции (щелчок ЛКМ на первом виджете, затем Ctrl+щелчок ЛКМ на остальных)
    7. вызвать выпадающее меню щелчком ПКМ на любом из выбранных виджетов
    8. в пункте меню Компоновка (Layout) выбрать пункт Скомпоновать по вертикали (Lay Out Vertically)
    9. перетащить на Scroll Area виджет Inputs Widgets/Plain Text Edit на свободное место слева
    10. выбрать виджеты QPlainTextEdit и QVBoxLayout для проведения групповой операции
    11. скомпоновать их по горизонтали
    12. выбрать вмджет QScrollArea и скомпоновать его по вертикали
    13. выбрать корневой виджет Form(QWidget) и скомпоновать его по горизонтали
    14. попробовать поменять размеры, потянув за правый нижний уголок формы
    15. если поведение соответствует ожиданиям - сохранить, иначе повторить сначала

    Вот теперь уже можно и тексты на кнопках поправить и прочие украшательства понавешать

    Возможен ещё экономичный вариант (пункты с 1 по 9 не меняются):
    10. выбрать виджет QScrollArea и скомпоновать его по горизонтали
    11. выбрать корневой виджет Form(QWidget) и скомпоновать его по вертикали
    12. попробовать поменять размеры, потянув за правый нижний уголок формы
    13. если поведение соответствует ожиданиям - сохранить, иначе повторить сначала

    Но возникают некие сомнения, что его удастся преобразовать в программерское решение без излишнего использования явного указания родителей при создании экземпляров классов. В первом-то случае, это удалось сделать, а тут непонятно...
    Запись от iamvic размещена 27.03.2024 в 22:20 iamvic вне форума
  7. Старый комментарий
    Тем не менее эти варианты исполнения являются полными функциональными аналогами, в чём можно убедиться после очередной переделки многострадального scroll_probe_ui.py, что позволит выбрать один из вариантов файла GUI при запуске приложения:
    Python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    #
    # Scroll Probe with UI file
    import os, sys
    from PyQt5 import (
        QtCore,
        QtWidgets,
        uic
        )
     
    class Scroll_probe(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(Scroll_probe, self).__init__(parent)
            f_ui = ('scroll_probe_eco.ui'
                if len(sys.argv) > 1 else 'scroll_probe.ui')
            uic.loadUi(f_ui, self)
            self.findChild(QtWidgets.QPlainTextEdit, 'plainTextEdit'
                ).setPlainText(f_ui)
     
        @QtCore.pyqtSlot(name='on_pushButton_pressed')
        @QtCore.pyqtSlot(name='on_pushButton_2_pressed')
        @QtCore.pyqtSlot(name='on_pushButton_3_pressed')
        @QtCore.pyqtSlot(name='on_pushButton_4_pressed')
        def on_button_pressed(self):
            self.findChild(QtWidgets.QPlainTextEdit, 'plainTextEdit'
                ).setPlainText('===> {!s} pressed'.format(
                    self.sender().text()
                    )
                )
     
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        if 'Windows' in QtWidgets.QStyleFactory.keys():
            app.setStyle(QtWidgets.QStyleFactory.create('Windows'))
     
        f_qss = 'scroll_probe_ui.qss'
        if (os.path.exists(f_qss) and os.path.isfile(f_qss)):
            t = ''
            with open(f_qss, 'r') as _from:
                t = _from.read()
            app.setStyleSheet(t)
     
        mwin = Scroll_probe()
        mwin.show()
        sys.exit(app.exec_())

    Вариант используемого файла GUI определяется наличием параметров в командной строке. Если параметры отсутствуют
    Bash
    1
    
    py scroll_probe_ui.py
    то используется уже существующий файл GUI scroll_probe.ui.

    А если есть хотя бы один дополнительный параметр, например,
    Bash
    1
    
    py scroll_probe_ui.py 1
    то используется экономичный вариант:
    Запись от iamvic размещена 29.03.2024 в 20:32 iamvic вне форума
  8. Старый комментарий
    scroll_probe_eco.ui
    XML
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>Form</class>
     <widget class="QWidget" name="Form">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>392</width>
        <height>265</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>Form</string>
      </property>
      <layout class="QVBoxLayout" name="verticalLayout_2">
       <item>
        <widget class="QScrollArea" name="scrollArea">
         <property name="widgetResizable">
          <bool>true</bool>
         </property>
         <widget class="QWidget" name="scrollAreaWidgetContents">
          <property name="geometry">
           <rect>
            <x>0</x>
            <y>0</y>
            <width>376</width>
            <height>249</height>
           </rect>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout">
           <item>
            <widget class="QPlainTextEdit" name="plainTextEdit"/>
           </item>
           <item>
            <layout class="QVBoxLayout" name="verticalLayout">
             <item>
              <widget class="QPushButton" name="pushButton">
               <property name="text">
                <string>Push Button 1</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QPushButton" name="pushButton_2">
               <property name="text">
                <string>Push Button 2</string>
               </property>
              </widget>
             </item>
             <item>
              <widget class="QPushButton" name="pushButton_3">
               <property name="text">
                <string>Push Button 3</string>
               </property>
              </widget>
             </item>
             <item>
              <spacer name="verticalSpacer">
               <property name="orientation">
                <enum>Qt::Vertical</enum>
               </property>
               <property name="sizeHint" stdset="0">
                <size>
                 <width>20</width>
                 <height>18</height>
                </size>
               </property>
              </spacer>
             </item>
             <item>
              <widget class="QPushButton" name="pushButton_4">
               <property name="text">
                <string>Push Button 4</string>
               </property>
              </widget>
             </item>
            </layout>
           </item>
          </layout>
         </widget>
        </widget>
       </item>
      </layout>
     </widget>
     <resources/>
     <connections/>
    </ui>
    Запись от iamvic размещена 29.03.2024 в 20:34 iamvic вне форума
  9. Старый комментарий
    Стилист тоже выполнил свою часть работы, разукрасив всё "под старину"
    scroll_probe_ui.qss

    CSS
    1
    2
    3
    4
    5
    6
    7
    
    Scroll_probe {background-color: palegoldenrod;}
    QScrollArea#scrollArea {border: 4px solid maroon; border-radius: 8;}
    QWidget#scrollAreaWidgetContents {background-color: darkseagreen;}
    QPlainTextEdit#plainTextEdit {background-color: lightgoldenrodyellow;
     font: bold; color: dimgrey;}
    QPushButton {background-color: palegoldenrod; font: bold;}
    QScrollBar {background-color: maroon; color: yellow;}
    Результат налицо

    Состав пакета:
    scroll_probe_ui.py
    scroll_probe.ui
    scroll_probe_eco.ui
    scroll_probe_ui.qss
    Запись от iamvic размещена 29.03.2024 в 20:43 iamvic вне форума
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru