Найти - Пользователи
Полная версия: PyQt5 Фиксированный размер окна и QGridLayout
Начало » GUI » PyQt5 Фиксированный размер окна и QGridLayout
1 2 3
gmaksim
Rodegast
Спасибо, и ты.

По теме:
В целом, не переделывая все подряд, можно сделать так:
 from PyQt5.QtCore import Qt
 self.layout = QGridLayout()
 self.layout.setAlignment(Qt.AlignTop)
Размещение идет по центру и если задать размер окна примерно 500 на 500, то в целом с небольшими изменения при помощи setMaximumWidth/setMaximumHeight на необходимый виджет, можно добиться оптимального результата.
py.user.next
gmaksim, ты Qt Designer'ом пользуёшься? Если нет, то пора начинать. Он создаёт ui-файл, который потом пропускается через pyuic4 или pyuic5 и дальше сгенерированный код подключается к скрипту. А все выравнивания виджетов делаются в дизайнере.

http://www.imageup.ru/img60/2825775/qtdes1.png.html
http://www.imageup.ru/img60/2825776/qtdes2.jpg.html
vic57
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_()
py.user.next
gmaksim
пробовал поставить Qt, но в opensource не входит designer (последний 5.9) судя по всему; сейчас попробую через pip
Дизайнер к питону вообще не относится, это отдельная программа; к питону относится транслятор pyuic5.
Ставишь дизайнер, ставишь питоновский транслятор для ui-файлов. Потом в дизайнере делаешь форму и сохраняешь (получается ui-файл, который сам по себе xml-файл такой). Потом этот ui-файл передаёшь в транслятор pyuic5 и он транслирует xml в питон-код (классы делает). И дальше уже ты наследуешься от этого класса в своём скрипте и твои окна принимают соответствующий вид.
Если тебе надо что-то поменять в окне (добавить кнопку, например), ты открываешь ui-файл в дизайнере, там меняешь, пересохраняешь, транслируешь и всё - твой код при запуске подцепляет класс и изменение появляется в окне.
gmaksim
Возвращаясь к вопросу, на более “живом” примере поясню вопрос.


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

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


Должна же быть какая-то возможность создания “контейнера” в рамках QGridLayout у которого будет свой размер, а другого контейнера другой - и все это на одном layout. Или QGridLayout не подходит для такой цели?
p.s. Про Qt Designer и прочее учел, но учитывая текущий функционал воспользоваться в этой ситуации с моим текущим опытом данным функционалом сложно (виджеты расставляются через функцию с заданными параметрами, которые “выдергиваются” из БД)
Kyrym
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_())
PEHDOM
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_()
andrey_krsk
Я новичок, поэтому тема для меня актуальная. Тоже пытался в QLayout выровнять верх с низом. И как в примере PEHDOMа не смог убрать промежуток между верхним и нижним виджетом. И внизу отступы от краев больше чем вверху. Видимо в QLayout нельзя их выровнять.
Kyrym
Сделать ровно можно, если основные виждеты вставить во фрейм, типа того:
 # 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 провернул расширение “модуля” по изменению габаритов главного окна я так и не понял. Кстати, цвета у вас (зелёный и красный) глазовырывательные.
PEHDOM
andrey_krsk
И внизу отступы от краев больше чем вверху. Видимо в QLayout нельзя их выровнять.
у куГридЛайота есть атрибут contentsMargins который отвечает за отступы от краев.
добавте в GridWidget
 .....
def __init__(self, parent=None):
        .......
        grid =  QGridLayout(self)
        grid.setContentsMargins(0,0,0,0)  # Устанавливаем отступы от краев
        .....
чтобы убрать отступы
Kyrym
Кстати, цвета у вас (зелёный и красный) глазовырывательные.
это не мое, я просто чутка переделпл пример vic57 к нему все претензии по поводу цветов
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB