Форум сайта python.su
Здравствуйте, столкнулся с задачей когда 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()
Отредактировано @cckyi_boxxx (Дек. 4, 2020 09:34:01)
Офлайн
@cckyi_boxxx
но стиолкнулся с тем что “управляется” он не так как уже привычные мне фреймворки,
@cckyi_boxxxАльтернатив полно!
Есть еще альтернативы, такие-же мощные и при этом bsd, mit и под подобными лицензиями?
#!/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)
Офлайн
> на pyqt все проще … Но долбаные лицензии мать имх не дают юзать привычное, надо как-то выкручиваться.
Там есть коммерческая лицензия. Ну и как бы LGPL совсем не GPL.
Офлайн
doza_and, спасибо за помощь, буду учить это 100%, просто обычно lgpl не мешали работать, а тут у меня неделя что-бы все закодить, вот и искал что-то максимально похожее на Qt, но под хорошей лицензией что-бы на требование предоставить серверную часть ПО или исходники клиентской смело слать требующего в эротический тур. Сейчас, глядя на ваш код, склоняюсь к тому что-бы сделать за неделю минимально-жизнеспособный продукт на Qt, а потом уже учить wx и перекодить все на него.
Rodegast, коммерческая есть, но стоит она совсем неадекватных денег, скажем 1000 уев я еще заплатил-бы за пожизненную, но то что требуют они, я столько не зарабатываю на этом, ибо не занимаюсь программированием профессионально, иногда фриланс, или как сейчас потребовалось service desk решение для себя самого и моих заказчиков по совершенно не связанной с программированием теме.
Офлайн
@cckyi_boxxxНу вообще то ядро Qt на LGPL-v2 Если ограничить функциональность Qt то помоему вы впишетесь в эту лицензию. Это будет не ваша головная боль а юристов которые должны будут это все оформлять.
коммерческая есть, но стоит она совсем неадекватных денег,
Офлайн
doza_andК сожалению моя, ибо софт пишу для своей будущей организации.
Это будет не ваша головная боль а юристов которые должны будут это все оформлять.
#-*- 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()
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
Офлайн
прорблему решил так, но вопрос почему сишная часть 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)
Офлайн
просто предположение …
Офлайн