Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » помогите с выбором фреймворка [RSS Feed]

#1 Дек. 4, 2020 09:30:45

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

Здравствуйте, столкнулся с задачей когда gpl или lgpl библиотеки использовать категорически нельзя, а возможностей Tkinter мало и без огромных костылей не выйдет. Начал выбирать альтернативы уже известным мне PyQt и PySide, попробовал wxpython, но стиолкнулся с тем что “управляется” он не так как уже привычные мне фреймворки, все эти автоматические упаковки в родителя без четкого приказа и многое другое говорит о том что с наскока изучить его, в процессе написания необходимого софта, у меня не выйдет. Есть еще альтернативы, такие-же мощные и при этом bsd, mit и под подобными лицензиями?

Если альтернативы нет то вот на чем я прогорел:

 import wx
import wx.grid
class GridSizerFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Basic Grid Sizer")
        self.SetBackgroundColour('white')
        
        sizer = wx.GridSizer(rows=2, cols=1, hgap=5, vgap=5) # создание основного сайзера (сетка)
        sizer2 = wx.BoxSizer(wx.HORIZONTAL) # создание сайзера для кнопок
        but = wx.Button(self, label='rrr') # левая кропка пока тупо для вида
        but2 = wx.Button(self) # левая кропка пока тупо для вида
        # теперь компонуем
        sizer2.Add(but)
        sizer2.Add(but2)
        sizer.Add(sizer2, 0,0)
        # двойное окно для двух таблиц
        self.sp = wx.SplitterWindow(self, id=-1, pos=wx.DefaultPosition,
                                    size=wx.DefaultSize, style=wx.SP_3D,
                                    name="splitterWindow")
        sizer.Add(self.sp, 0, flag = wx.ALIGN_TOP) # почему-то не работает wx.ALIGN_TOP
        # g1 - первая таблица, 
        g1 = wx.grid.Grid(self.sp, style=wx.SUNKEN_BORDER)
        g1.CreateGrid(2,1)
        g1.SetDefaultColSize(300, resizeExistingCols=False)
        g1.SetScrollbar(wx.VERTICAL, wx.LEFT, 5, 1000, refresh=True)
        g1.SetCellValue(0,0,'butt')
        
        grid = wx.grid.Grid(self.sp, style=wx.SUNKEN_BORDER)
        grid.CreateGrid(50,50)
        grid.SetScrollbar(wx.VERTICAL, wx.RIGHT, 100, 100, refresh=True) # появление скролбара не наблюдается и скролится все криво какие-бы параметры я не стапвил
        #grid.SetScrollbar(orientation, position, thumbSize, range, refresh=True)
        # заполняем таблицы
        grid.SetCellValue(0,0,'butt')
        for row in range(20): 
            for col in range(6):
                grid.SetCellValue(row, col, "cell (%d,%d)" % (row, col))
        #self.sp.Initialize(g1)                     # Инициализация разделителя
        #self.sp.Initialize(grid)
        # финиш
        self.sp.SplitVertically(g1, grid, sashPosition=450)
        self.SetSizer(sizer)
        self.Fit()
app = wx.PySimpleApp()
GridSizerFrame().Show(True)
app.MainLoop()
после некоторого количества секса с wx смог слепить это, как и ожидалось работает совсем не так как хочется (картинка кликабельна):


ps: на pyqt все проще, FormLayout в который две таблицы (он их автоматом обровняет) и тулбар под кнопки, а тут … Но долбаные лицензии мать имх не дают юзать привычное, надо как-то выкручиваться.



Отредактировано @cckyi_boxxx (Дек. 4, 2020 09:34:01)

Офлайн

#2 Дек. 4, 2020 15:07:05

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4089
Репутация: +  250  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

@cckyi_boxxx
но стиолкнулся с тем что “управляется” он не так как уже привычные мне фреймворки,
@cckyi_boxxx
Есть еще альтернативы, такие-же мощные и при этом bsd, mit и под подобными лицензиями?
Альтернатив полно!
https://wiki.python.org/moin/GuiProgramming
можно смотреть PyGtk, kivi. sefpython ….
И смею вас уверить, они все будут управляться совершенно не так как Qt. wxPython наверное самая мощная из альтернатив.
Так что собирайте волю в кулак и учите новый фреймворк.

Разобраться в вашем коде довольно сложно.
Мне непонятно зачем вы используете grid если у вас одна колонка. Вам нужен обычный вертикальный разместитель.
Борьба со скроллбарами мне неясна. Ему никакие параетры не надо задават. Скроллбары по умолчанию есть и работают как надо.

Судя по app = wx.PySimpleApp() вы пользуетесь какимито очень древними книжками по WX. найдите чтото посовременнее.

А так да. Инструменты размещения элементов в wx другие. И на мой взгляд они мощнее инструментов Qt :). обратите внимение на параметр Proportion.
 #!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# generated by wxGlade 0.9.4 on Fri Dec  4 16:14:41 2020
#
import wx
import wx.grid
# begin wxGlade: dependencies
# end wxGlade
# begin wxGlade: extracode
# end wxGlade
class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((696, 533))
        self.button_4 = wx.Button(self, wx.ID_ANY, "button_4")
        self.button_5 = wx.Button(self, wx.ID_ANY, "button_5")
        self.grid_3 = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))
        self.grid_4 = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))
        self.__set_properties()
        self.__do_layout()
        # end wxGlade
    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle("frame")
        self.grid_3.CreateGrid(50,50)
        self.grid_4.CreateGrid(50,50)
        # end wxGlade
    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2.Add(self.button_4, 0, 0, 0)
        sizer_2.Add(self.button_5, 0, 0, 0)
        sizer_1.Add(sizer_2, 0, wx.EXPAND, 0)
        sizer_3.Add(self.grid_3, 1, wx.EXPAND, 0)
        sizer_3.Add(self.grid_4, 1, wx.EXPAND, 0)
        sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
        # end wxGlade
# end of class MyFrame
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True
# end of class MyApp
if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()



Отредактировано doza_and (Дек. 4, 2020 15:27:47)

Офлайн

#3 Дек. 4, 2020 21:20:00

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2535
Репутация: +  177  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

> на pyqt все проще … Но долбаные лицензии мать имх не дают юзать привычное, надо как-то выкручиваться.

Там есть коммерческая лицензия. Ну и как бы LGPL совсем не GPL.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#4 Дек. 5, 2020 10:55:02

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

doza_and, спасибо за помощь, буду учить это 100%, просто обычно lgpl не мешали работать, а тут у меня неделя что-бы все закодить, вот и искал что-то максимально похожее на Qt, но под хорошей лицензией что-бы на требование предоставить серверную часть ПО или исходники клиентской смело слать требующего в эротический тур. Сейчас, глядя на ваш код, склоняюсь к тому что-бы сделать за неделю минимально-жизнеспособный продукт на Qt, а потом уже учить wx и перекодить все на него.

Rodegast, коммерческая есть, но стоит она совсем неадекватных денег, скажем 1000 уев я еще заплатил-бы за пожизненную, но то что требуют они, я столько не зарабатываю на этом, ибо не занимаюсь программированием профессионально, иногда фриланс, или как сейчас потребовалось service desk решение для себя самого и моих заказчиков по совершенно не связанной с программированием теме.



Офлайн

#5 Дек. 6, 2020 14:50:27

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4089
Репутация: +  250  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

@cckyi_boxxx
коммерческая есть, но стоит она совсем неадекватных денег,
Ну вообще то ядро Qt на LGPL-v2 Если ограничить функциональность Qt то помоему вы впишетесь в эту лицензию. Это будет не ваша головная боль а юристов которые должны будут это все оформлять.



Офлайн

#6 Дек. 7, 2020 15:52:35

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

doza_and
Это будет не ваша головная боль а юристов которые должны будут это все оформлять.
К сожалению моя, ибо софт пишу для своей будущей организации.

у меня тут новая проблема с wx назрела, решился все-таки сразу на нем пилить, не намного он сложнее Qt, выкладываю весь код gui, а прорблемное место в нем обозначено соответствующим коментарием (СТРАННЫЕ ДЕЛА ТВОРЯТСЯ ЗДЕСЬ).

 #-*- coding:utf-8 -*-
import wx
import wx.grid
from wx.lib import wordwrap
import locale
locale.setlocale(locale.LC_ALL,'ru')# locale.locale_alias['ru'])
class CutomGridCellAutoWrapStringRenderer(wx.grid.GridCellRenderer):   
    def __init__(self): 
        """класс костыль для автоматического расширения ячеек при многострочном заполнении"""
        wx.grid.GridCellRenderer.__init__(self)
    def Draw(self, grid, attr, dc, rect, row, col, isSelected):
        text = grid.GetCellValue(row, col)
        dc.SetFont( attr.GetFont() ) 
        text = wordwrap.wordwrap(text, grid.GetColSize(col), dc, breakLongWords = False)
        # начало моего костыля
        numlines = text.count('\n') + 1
        defrowsize = grid.GetDefaultRowSize()
        currowsize = grid.GetRowSize(row)
        needrowsize = currowsize // defrowsize 
        if numlines > needrowsize:
            newrowsize = numlines * defrowsize
            grid.SetRowSize(row, newrowsize)
        # конец моего костыля
        hAlign, vAlign = attr.GetAlignment()       
        if isSelected: 
            bg = grid.GetSelectionBackground() 
            fg = grid.GetSelectionForeground() 
        else: 
            bg = attr.GetBackgroundColour()
            fg = attr.GetTextColour() 
        dc.SetTextBackground(bg) 
        dc.SetTextForeground(fg)
        dc.SetBrush(wx.Brush(bg, wx.SOLID))
        dc.SetPen(wx.TRANSPARENT_PEN)
        dc.DrawRectangle(rect)            
        grid.DrawTextRectangle(dc, text, rect, hAlign, vAlign)
    def GetBestSize(self, grid, attr, dc, row, col): 
        text = grid.GetCellValue(row, col)
        dc.SetFont(attr.GetFont())
        text = wordwrap.wordwrap(text, grid.GetColSize(col), dc, breakLongWords = False)
        w, h, lineHeight = dc.GetMultiLineTextExtent(text)                   
        return wx.Size(w, h)        
    def Clone(self): 
        return CutomGridCellAutoWrapStringRenderer()
class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        """This class provides graphical interface declaration and base signal processing"""
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        # start calc window sizes and apply its
        dis_width, dis_height = wx.DisplaySize()
        dis_width = dis_width - (dis_width // 10)
        dis_height = dis_height - (dis_height // 10)
        self.SetMinClientSize((dis_width, dis_height))
        self.SetPosition((0,0))
        self.Maximize(maximize=True)
        # end  calc window sizes and apply its
        self.button_4 = wx.Button(self, wx.ID_ANY, "button_4")
        self.button_5 = wx.Button(self, wx.ID_ANY, "button_5")
        self.grid_3 = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))
        self.grid_4 = wx.grid.Grid(self, wx.ID_ANY, size=(1, 1))
        self.__set_properties()
        self.__do_layout()
        
    def __set_properties(self):
        """configure widgets here"""
        self.SetTitle("My service desk")
        self.grid_3.CreateGrid(200,1)
        self.grid_3.SetMaxSize((400,-1))
        self.grid_3.SetColSize(0, 330)
        self.grid_3.SetRowLabelSize(50)
        self.grid_3.SetCornerLabelValue("№")
        self.grid_3.SetColLabelValue(0, "Список заявок")
        self.grid_3.SetDefaultRenderer(CutomGridCellAutoWrapStringRenderer())
        self.grid_3.SetCellValue(0, 0, 'rfb zdfnb dzxngb zdfnb zdfnb zdfnnb zdxfnb zdfnb zdfnb zdnb zdfnb \n\n\nszdfrn zdxfngb zdfxn zxfn sdzfnh dzrsfnh zdfxn sdfxng sdgtn sdfn sdxfn ')
        self.grid_4.CreateGrid(200,50)
        self.grid_4.SetDefaultRenderer(CutomGridCellAutoWrapStringRenderer())
        self.grid_4.SetSelectionMode(self.grid_4.SelectRows)
        self.__create_table_colors()
        ########################      СТРАННЫЕ ДЕЛА ТВОРЯТСЯ ЗДЕСЬ ##############################################################
        #"""
        ''' вариант 1
        '''
        self._tables_apply_default_colors()
        self.grid_4.SetRowAttr(3, self.work_done_green_row)
        self.grid_4.SetRowAttr(3, self.gray_row)
        #"""
        
        """
        ''' вариант 2
        '''
        self._tables_apply_default_colors()
        self.grid_4.SetRowAttr(3, self.work_done_green_row)
        #self.grid_4.SetRowAttr(3, self.gray_row)
        #"""
        
        """
        ''' вариант 3
        '''
        self._tables_apply_default_colors()
        #self.grid_4.SetRowAttr(3, self.work_done_green_row)
        #self.grid_4.SetRowAttr(3, self.gray_row)
        #"""
        
        """
        ''' вариант 4
        '''
        #self._tables_apply_default_colors()
        self.grid_4.SetRowAttr(3, self.work_done_green_row)
        self.grid_4.SetRowAttr(3, self.gray_row)
        #"""
        self.__connect_slots_at_startup()
        
        
    def _tables_apply_default_colors(self):
        """in this method i apply default table colors"""
        self.grid_3.SetGridLineColour("#cccccc")
        self.grid_4.SetGridLineColour("#cccccc")
        for x in range(self.grid_3.GetNumberRows()):
            if (x+1) % 2 != 0: self.grid_3.SetRowAttr(x, self.white_row)
            else: self.grid_3.SetRowAttr(x, self.gray_row)
        for x in range(self.grid_4.GetNumberRows()):
            if (x+1) % 2 != 0: self.grid_4.SetRowAttr(x, self.white_row)
            else: self.grid_4.SetRowAttr(x, self.gray_row)
        
        
    
    def __create_table_colors(self):
        """this method create colors for rows"""
        self.white_row = wx.grid.GridCellAttr()
        self.white_row.SetBackgroundColour("#ffffff")
        self.gray_row = wx.grid.GridCellAttr()
        self.gray_row.SetBackgroundColour("#f3f3f3")
        self.work_done_green_row = wx.grid.GridCellAttr()
        self.work_done_green_row.SetBackgroundColour("#98FB98")
        
        
    def __do_layout(self):
        """"""
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2.Add(self.button_4, 0, 0, 0)
        sizer_2.Add(self.button_5, 0, 0, 0)
        sizer_1.Add(sizer_2, 0, wx.EXPAND, 0)
        sizer_3.Add(self.grid_3, 1, wx.EXPAND, 0)
        sizer_3.Add(self.grid_4, 1, wx.EXPAND, 0)
        sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
    
    def __connect_slots_at_startup(self):
        self.grid_3.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self._slot_grid3_cell_clicked)
        
    ############################################################### SLOTS ##################################################################
    def _slot_grid3_cell_clicked(self, evt):
        """здесь получаем имя заявки и передаем ее на подгрузку деталей в таблицу"""
        clicked_row = evt.GetRow()
        proposal_name = self.grid_3.GetCellValue(clicked_row, 0)
        self.grid_3.SelectRow(clicked_row, addToSelected=False)
        
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MyFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True
# end of class MyApp
if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

вариант 1 выдает такую ошибку:
17:40:01: ������: Unable to set default locale: 'unsupported locale setting'
Traceback (most recent call last):
File "C:\Users\dev\Documents\Python Code\sdesk\guilibs.py", line 173, in OnInit
self.frame = MyFrame(None, wx.ID_ANY, "")
File "C:\Users\dev\Documents\Python Code\sdesk\guilibs.py", line 67, in __init__
self.__set_properties()
File "C:\Users\dev\Documents\Python Code\sdesk\guilibs.py", line 91, in __set_properties
self.grid_4.SetRowAttr(3, self.gray_row)
RuntimeError: wrapped C/C++ object of type GridCellAttr has been deleted
OnInit returned false, exiting...
Error in atexit._run_exitfuncs:
wx._core.wxAssertionError: C++ assertion "m_count > 0" failed at ..\..\src\common\object.cpp(336) in wxRefCounter::DecRef(): invalid ref data count

вариант 2 другую (картинка кликабельна):


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



Офлайн

#7 Дек. 8, 2020 08:20:19

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

прорблему решил так, но вопрос почему сишная часть wx удаляет еще используемые объекты и как это пофиксить остается открытым.

 def colorize_row(self, gridobj, row, color):
        """method set row background color"""
        numcols = gridobj.GetNumberCols()
        for x in range(numcols):
            gridobj.SetCellBackgroundColour(row, x, color)



Офлайн

#8 Дек. 8, 2020 17:42:38

AD0DE412
Зарегистрирован: 2019-05-12
Сообщения: 889
Репутация: +  40  -
Профиль   Отправить e-mail  

помогите с выбором фреймворка

просто предположение



1. пжлст, форматируйте код, это в панели создания сообщений, выделите код и нажмите что то вроде
2. чтобы вставить изображение залейте его куда нибудь (например), нажмите и вставьте ссылку на его url

есчщо

Офлайн

  • Начало
  • » GUI
  • » помогите с выбором фреймворка[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version