Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » PyQt5 Фиксированный размер окна и QGridLayout [RSS Feed]

#1 Авг. 2, 2017 14:54:28

gmaksim
От: Россия
Зарегистрирован: 2017-07-17
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

Rodegast
Спасибо, и ты.

По теме:
В целом, не переделывая все подряд, можно сделать так:

 from PyQt5.QtCore import Qt
 self.layout = QGridLayout()
 self.layout.setAlignment(Qt.AlignTop)
Размещение идет по центру и если задать размер окна примерно 500 на 500, то в целом с небольшими изменения при помощи setMaximumWidth/setMaximumHeight на необходимый виджет, можно добиться оптимального результата.

Офлайн

#2 Авг. 3, 2017 03:14:40

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

PyQt5 Фиксированный размер окна и QGridLayout

gmaksim, ты Qt Designer'ом пользуёшься? Если нет, то пора начинать. Он создаёт ui-файл, который потом пропускается через pyuic4 или pyuic5 и дальше сгенерированный код подключается к скрипту. А все выравнивания виджетов делаются в дизайнере.

http://www.imageup.ru/img60/2825775/qtdes1.png.html
http://www.imageup.ru/img60/2825776/qtdes2.jpg.html



Отредактировано py.user.next (Авг. 3, 2017 03:22:16)

Офлайн

#3 Авг. 3, 2017 04:36:26

vic57
Зарегистрирован: 2015-07-07
Сообщения: 899
Репутация: +  126  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

gmaksim
Как можно осуществить следующее:
Задать фиксированный размер окна (черный контур) и при этом в рамках него задать QGridLayout другого фиксированного размера (фиолетовый контур)?
создай вложенный виджет со своим лэйаутом
 from PyQt4.QtGui import *
class W1(QFrame):
     def __init__(self,parent=None):
         QFrame.__init__(self,parent)
         self.setFixedSize(200,200)
         self.setStyleSheet("QFrame {background-color: red;}")
                      
        
class W(QWidget):
     def __init__(self,parent=None):
         QWidget.__init__(self,parent)
         self.setStyleSheet("QWidget {background-color: green;}")
         w1 = W1(self)
         w1.move(0,0)
 
app = QApplication([])
w = W()
w.resize(400,400)
w.show()
app.exec_()

Отредактировано vic57 (Авг. 3, 2017 04:59:11)

Офлайн

#4 Авг. 4, 2017 00:31:45

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

PyQt5 Фиксированный размер окна и QGridLayout

gmaksim
пробовал поставить Qt, но в opensource не входит designer (последний 5.9) судя по всему; сейчас попробую через pip
Дизайнер к питону вообще не относится, это отдельная программа; к питону относится транслятор pyuic5.
Ставишь дизайнер, ставишь питоновский транслятор для ui-файлов. Потом в дизайнере делаешь форму и сохраняешь (получается ui-файл, который сам по себе xml-файл такой). Потом этот ui-файл передаёшь в транслятор pyuic5 и он транслирует xml в питон-код (классы делает). И дальше уже ты наследуешься от этого класса в своём скрипте и твои окна принимают соответствующий вид.
Если тебе надо что-то поменять в окне (добавить кнопку, например), ты открываешь ui-файл в дизайнере, там меняешь, пересохраняешь, транслируешь и всё - твой код при запуске подцепляет класс и изменение появляется в окне.



Отредактировано py.user.next (Авг. 4, 2017 00:33:01)

Офлайн

#5 Сен. 14, 2017 14:44:27

gmaksim
От: Россия
Зарегистрирован: 2017-07-17
Сообщения: 42
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

Возвращаясь к вопросу, на более “живом” примере поясню вопрос.


При использовании QGridLayout выходит так, что виджеты автоматически “ресайзятся”. Это удобно, но в моей ситуации приводит к неоднородному виду QLineEdit (оранжевая область).

Хочется (да простят меня повелители фотошопа) примерно такого результата:


Должна же быть какая-то возможность создания “контейнера” в рамках QGridLayout у которого будет свой размер, а другого контейнера другой - и все это на одном layout. Или QGridLayout не подходит для такой цели?
p.s. Про Qt Designer и прочее учел, но учитывая текущий функционал воспользоваться в этой ситуации с моим текущим опытом данным функционалом сложно (виджеты расставляются через функцию с заданными параметрами, которые “выдергиваются” из БД)

Отредактировано gmaksim (Сен. 14, 2017 14:47:43)

Офлайн

#6 Сен. 14, 2017 15:53:26

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

gmaksim
Возвращаясь к вопросу, на более “живом” примере поясню вопрос.

Мне кажется, что это уже другой вопрос. Переписку не перечитывал, но вроде было: как вставить окно с фиксированным размером? А сейчас: как вставить и подогнать под размер? В данном случае вставляете зелёный прямоугольник, подгоняя под оранжевый?

Покажу такой пример. Два файла: главный - index, модуль - mod. Mod вставляем в index.
Index.py
 # Python 3. PyQt4
# -*- coding: utf-8 -*-
import sys
import mod
from PyQt4 import QtGui, QtCore
# Графика
class Window_os(QtGui.QWidget):
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent)        
        self.resize(600, 600)
        self.setWindowTitle('Зап модуля') # Заголовок
      
        # БЛОК РАЗМЕТКИ
        grid = QtGui.QGridLayout() # создание сетки
        self.lbl_1 = QtGui.QLabel('<font color="red"> <H2>Текст основной'+
                                  ' программы</H2><font>')
        grid.addWidget(self.lbl_1, 0,0)
        # --- ---
        frame_1 = QtGui.QFrame()
        frame_1.setFrameShape(1) # 0 - отключить рамку
        frame_1_lay = QtGui.QGridLayout(frame_1)
        grid.addWidget(frame_1, 1,0) # Фрейм 1
        # ---
        viewport = mod.Window() # импорт модуля
        #viewport.setMaximumSize(600, 300)
        viewport.setMinimumSize(600, 300)
        frame_1_lay.addWidget(viewport, 1,0, alignment=QtCore.Qt.AlignLeft)
        # --- ---
        self.pole = QtGui.QTextEdit('<H2>Поле основной программы<H2>')
        grid.addWidget(self.pole, 2,0)
        # --- ---
        self.setLayout(grid) # установка менеджера компоновки
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window_os() # создаёт экземпляр окна из класса    
    window.show() # запускает окно
    sys.exit(app.exec_())
Mod.py Этот код смотреть не надо, он нужен для вставки.
 # Python 3. PyQt4
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
# Графика
class Window(QtGui.QWidget): # Класс Window  наследует класс QWidget
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent)        
        self.resize(300, 300) 
        self.setWindowTitle('Расчёт объёма') # Заголовок
        
        # БЛОК СОЗДАНИЯ LABEL
        self.lbl_a = QtGui.QLabel('Длина a =')
        self.lbl_b = QtGui.QLabel('Ширина b =')
        self.lbl_h = QtGui.QLabel('Высота h =')
        self.lbl_console = QtGui.QLabel('Расчёт')
        self.lbl_vvod = QtGui.QLabel('Ввод')
        
        self.lbl_help = QtGui.QLabel() # Создаём текстовую строку
      
        # БЛОК СОЗДАНИЯ ПОЛЕЙ
        self.pole_a = QtGui.QLineEdit('10')
        self.pole_a.returnPressed.connect(self.on_save_isd)
        
        self.pole_b = QtGui.QLineEdit('6')
        self.pole_b.returnPressed.connect(self.on_save_isd)
        
        self.pole_h = QtGui.QLineEdit('2')
        self.pole_h.returnPressed.connect(self.on_save_isd)
        
        self.pole_console = QtGui.QTextEdit() # Показывает ход вычислений        
        self.pole_vvod = QtGui.QLineEdit() 
        # БЛОК СОЗДАНИЯ КНОПОК
        self.button_1 = QtGui.QPushButton('Ввести') 
        self.button_2 = QtGui.QPushButton('Расчёт') # Запуск расчёта
        self.button_2.clicked.connect(self.on_click)
        self.button_open_isd = QtGui.QPushButton('Открыть ИД')
        self.button_open_isd.clicked.connect(self.on_open_isd)
        
        self.button_save_isd = QtGui.QPushButton('Сохранить ИД')
        self.button_save_isd.clicked.connect(self.on_save_isd)
        # БЛОК РАЗМЕТКИ
        grid = QtGui.QGridLayout() # создание сетки
        grid.setSpacing(5) # Устанавливает расстояние между компонентами
        grid.addWidget(self.button_open_isd, 0, 0)
        grid.addWidget(self.button_save_isd, 0, 1)
        grid.addWidget(self.lbl_a, 1, 0)
        grid.addWidget(self.pole_a, 1, 1)
                
        grid.addWidget(self.lbl_b, 2, 0)
        grid.addWidget(self.pole_b, 2, 1)
        grid.addWidget(self.lbl_h, 3, 0)
        grid.addWidget(self.pole_h, 3, 1)
        grid.addWidget(self.lbl_console, 4, 0)
        grid.addWidget(self.pole_console, 4,1,1,2)
        grid.addWidget(self.button_2, 0, 2)
        grid.addWidget(self.lbl_vvod, 5, 0)
        grid.addWidget(self.pole_vvod, 5,1,1,1)
        grid.addWidget(self.button_1, 5, 2)
        grid.addWidget(self.lbl_help, 1, 2)
            
        self.setLayout(grid) # установка менеджера компоновки
    # ЛОГИКА
    def on_click(self):
        def ap(i): # ap('aa') 
            data.append(i)
        def aps(i): # aps(['aa','aa'])
            i = ''.join(map(str, i))
            data.append(str(i))
        data = []
        self.pole_console.setText('')
        
        a = float(self.pole_a.text())
        b = float(self.pole_b.text())
        h = float(self.pole_h.text())
        V = a*b*h
        aps(["V = a∙b∙h = ",a,"∙",b,"∙",h," = ",V])
        
        for i in data:
            self.pole_console.append(str(i))
    def on_open_isd (self):
        pass    
    
    def on_save_isd (self):
        pass
 
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window() # создаёт экземпляр окна из класса    
    window.show() # запускает окно
    sys.exit(app.exec_())

В файле Index посмотрите на строчки:
 viewport.setMaximumSize(600, 300)
viewport.setMinimumSize(600, 300)
Первая вставит mod.py с нужным размером (как я писал в начале темы, размеры можете импортировать из mod.py в index.py)
Вторая строчка будет растягивать окно, как Вы спрашивали в своём последнем сообщении.
————————
Да, и можно обойтись без фрейма, если рамка не нужна:
 # Python 3. PyQt4
# -*- coding: utf-8 -*-
import sys
import mod
from PyQt4 import QtGui, QtCore
# Графика
class Window_os(QtGui.QWidget):
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent)        
        self.resize(600, 600)
        self.setWindowTitle('Зап модуля') # Заголовок
      
        # БЛОК РАЗМЕТКИ
        grid = QtGui.QGridLayout() # создание сетки
        self.lbl_1 = QtGui.QLabel('<font color="red"> <H2>Текст основной'+
                                  ' программы</H2><font>')
        grid.addWidget(self.lbl_1, 0,0)
        # --- ---        
        viewport = mod.Window() # импорт модуля
        viewport.setMaximumSize(600, 300)
        #viewport.setMinimumSize(600, 300)
        grid.addWidget(viewport, 1,0, alignment=QtCore.Qt.AlignLeft)
        # --- ---
        self.pole = QtGui.QTextEdit('<H2>Поле основной программы<H2>')
        grid.addWidget(self.pole, 2,0)
        # --- ---
        self.setLayout(grid) # установка менеджера компоновки
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window_os() # создаёт экземпляр окна из класса    
    window.show() # запускает окно
    sys.exit(app.exec_())

Отредактировано Kyrym (Сен. 14, 2017 16:00:39)

Офлайн

#7 Сен. 14, 2017 16:35:20

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

gmaksim
Должна же быть какая-то возможность создания “контейнера” в рамках QGridLayout у которого будет свой размер,
QWidget же. Создайте новый КуВиджет, в него помещайте свой КуГридЛайот, в него кидайте ваши виджеты, настраиваете как они должны растягиваться, сжиматься, а потом все это пихайте на форму.
Или просто можно внутрь одного лайота поместить другой, .
чутка доработал пример vic57
в примере верхние прямоугольники помешаються внутри QHBoxLayout, котороы1 в свою очередь помещен в QVBoxLayout
А нижние в отдельном виджете, в котором уже свой QGridLayout
 from PyQt4.QtGui import *
class W1(QFrame):
     def __init__(self,parent=None):
         QFrame.__init__(self,parent)
         #self.setMinimumSize(200,200)
         self.setStyleSheet("QFrame {background-color: red;}")
class GridWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        grid =  QGridLayout(self)
        for i in range(3):
            for j in range(6):
                f = W1()
                grid.addWidget(f, i, j)
class W(QWidget):
     def __init__(self,parent=None):
         QWidget.__init__(self, parent)
         self.setStyleSheet("QWidget {background-color: green;}")
         wLayout = QVBoxLayout(self)
         hLayout = QHBoxLayout(self)
         wLayout.addLayout(hLayout)
         for i in range (4):
             w1 = W1(self)
             hLayout.addWidget(w1)
         g1 = GridWidget(self)
         wLayout.addWidget(g1)
app = QApplication([])
w = W()
w.resize(400,400)
w.show()
app.exec_()



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Сен. 14, 2017 16:59:11)

Офлайн

#8 Сен. 20, 2017 18:11:29

andrey_krsk
Зарегистрирован: 2017-09-06
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

Я новичок, поэтому тема для меня актуальная. Тоже пытался в QLayout выровнять верх с низом. И как в примере PEHDOMа не смог убрать промежуток между верхним и нижним виджетом. И внизу отступы от краев больше чем вверху. Видимо в QLayout нельзя их выровнять.

Офлайн

#9 Сен. 20, 2017 22:54:43

Kyrym
Зарегистрирован: 2016-12-28
Сообщения: 225
Репутация: +  3  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

Сделать ровно можно, если основные виждеты вставить во фрейм, типа того:

 # Python 3. PyQt4
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
# Графика
class Window_os(QtGui.QWidget):
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent)        
        self.resize(600, 600)
        self.setWindowTitle('Зап модуля') # Заголовок
      
        # БЛОК РАЗМЕТКИ
        grid = QtGui.QGridLayout() # создание сетки
        self.lbl_1 = QtGui.QLabel('<font color="red"> <H2>Текст основной'+
                                  ' программы</H2><font>')
        grid.addWidget(self.lbl_1, 0,0)
        # self.setStyleSheet("QFrame {background-color: #2e6979;}")
        # --- ---
        
        viewport = Mod(self) # импорт модуля
        viewport.setStyleSheet("background-color: #517852; text-align: justify")
        grid.addWidget(viewport, 1,0)
        # --- ---
        frame_1 = QtGui.QFrame()
        frame_1.setFrameShape(0) # 0 - отключить рамку
        frame_1_lay = QtGui.QGridLayout(frame_1)
        grid.addWidget(frame_1, 2,0) # Фрейм 1
        # ---
        self.pole = QtGui.QTextEdit('<H2>Поле основной программы<H2>')
        frame_1_lay.addWidget(self.pole, 0,0)
        # --- ---
        self.btn = QtGui.QPushButton('Вставить')
        frame_1_lay.addWidget(self.btn, 1,0)
        # --- ---
        self.setLayout(grid) # установка менеджера компоновки
class Mod(QtGui.QWidget):
    def __init__(self, parent=None): 
        QtGui.QWidget.__init__(self, parent)        
        
        # БЛОК РАЗМЕТКИ
        hbox = QtGui.QHBoxLayout() # создание сетки
        pole1 = QtGui.QTextEdit()        
        hbox.addWidget(pole1)
        # ---
        pole2 = QtGui.QTextEdit()
        hbox.addWidget(pole2)
        # --- ---
        self.setLayout(hbox) # установка менеджера компоновки
# КОНЕЦ
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = Window_os() # создаёт экземпляр окна из класса    
    window.show() # запускает окно
    sys.exit(app.exec_())
Как PEHDOM провернул расширение “модуля” по изменению габаритов главного окна я так и не понял. Кстати, цвета у вас (зелёный и красный) глазовырывательные.

Отредактировано Kyrym (Сен. 20, 2017 23:12:16)

Офлайн

#10 Сен. 21, 2017 10:19:12

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

PyQt5 Фиксированный размер окна и QGridLayout

andrey_krsk
И внизу отступы от краев больше чем вверху. Видимо в QLayout нельзя их выровнять.
у куГридЛайота есть атрибут contentsMargins который отвечает за отступы от краев.
добавте в GridWidget
 .....
def __init__(self, parent=None):
        .......
        grid =  QGridLayout(self)
        grid.setContentsMargins(0,0,0,0)  # Устанавливаем отступы от краев
        .....
чтобы убрать отступы
Kyrym
Кстати, цвета у вас (зелёный и красный) глазовырывательные.
это не мое, я просто чутка переделпл пример vic57 к нему все претензии по поводу цветов



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

  • Начало
  • » GUI
  • » PyQt5 Фиксированный размер окна и QGridLayout[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version