Найти - Пользователи
Полная версия: Работа с динамической таблицей (ввод массива данных через GUI-интерфейс)
Начало » Python для новичков » Работа с динамической таблицей (ввод массива данных через GUI-интерфейс)
1 2
taxol
Всем доброго времени суток! Ввиду производственной необходимости только приступил к изучению Python. Прошу помощи у маститых программистов. Думаю, для Вас задача тривиальная.

Имеется переменная, обозначающая количество проб — N, это количество пользователь вносит в поле ввода Entry (GUI). Допустим, = 5. В той же GUI-форме создается таблица 2х5 (два столбца, пять строк), в которую пользователь переносит данные из таблицы, находящейся в другом документе. Таблица сохраняется в .xlsx
В-принципе, массив с данными может сохраняться в любом формате, лишь бы можно было легко ее скопировать (открыть в блокноте) и перенести в .xlsx
При N=50, создается таблица 2х50.

AD0DE412
че надо то gui? xlsx?
taxol
Необходим GUI. Допустим, есть однострочное текстовое поле, куда пользователь вводит число. Пусть это будет 25. Тут же выводится таблица с количеством строк 25. В эти строки пользователь вбивает данные и сохраняет в любом формате.
doza_and
taxol
лишь бы можно было легко ее скопировать (открыть в блокноте) и перенести в .xlsx
Я наверное чегото не понимаю. Мне постановка задачи кажется абсурдной.
Зачем нужен GUI чтобы ввести число строк, чтобы строить таблицу, чтобы потом ее заполнить, чтобы данные перенести в эксел. Если можно просто открыть эксел и их туда ввести?

Какой usecase вы предполагаете? Вы хотите чтобы было ровно заданное число строк? Те вы посчитаете число строк, наберете число, а потом будете вбивать? Или вас смущает что эксел долго открывается? Или вы хотите малюсенькое окно сделать, чтобы оно на экране меньше места занимало? Так потом все равно эксел будете открывать.
AD0DE412


 # -*- coding: utf-8 -*- 
###########################################################################
## Python code generated with wxFormBuilder (version Jun 17 2015)
## http://www.wxformbuilder.org/
##
## PLEASE DO "NOT" EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
import csv
###########################################################################
## Python 2.7
## wx-3.0-msw
###########################################################################
class MyFrame ( wx.Frame ):
    def __init__( self, parent ):
        wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"xz", pos = wx.DefaultPosition, size = wx.Size( 355,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
        self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
        bSizer1 = wx.BoxSizer( wx.VERTICAL )
        bSizer3 = wx.BoxSizer( wx.HORIZONTAL )
        self.m_spinCtrl1 = wx.SpinCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.SP_ARROW_KEYS, 1, 1000000, 0 )
        bSizer3.Add( self.m_spinCtrl1, 1, wx.ALL, 5 )
        self.m_button1 = wx.Button( self, wx.ID_ANY, u"ok", wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer3.Add( self.m_button1, 0, wx.ALL, 5 )
        bSizer1.Add( bSizer3, 0, wx.EXPAND, 5 )
        bSizer4 = wx.BoxSizer( wx.VERTICAL )
        self.m_scrolledWindow3 = wx.ScrolledWindow( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.HSCROLL|wx.VSCROLL )
        self.m_scrolledWindow3.SetScrollRate( 5, 5 )
        self.bSizer9 = wx.BoxSizer( wx.VERTICAL )
        self.tbl = []
        self.bSizer9.Add( self.xz(), 1, wx.EXPAND, 5 )
        self.m_scrolledWindow3.SetSizer( self.bSizer9 )
        self.m_scrolledWindow3.Layout()
        self.bSizer9.Fit( self.m_scrolledWindow3 )
        bSizer4.Add( self.m_scrolledWindow3, 1, wx.EXPAND |wx.ALL, 5 )
        bSizer1.Add( bSizer4, 1, wx.EXPAND, 5 )
        bSizer6 = wx.BoxSizer( wx.HORIZONTAL )
        self.m_button5 = wx.Button( self, wx.ID_ANY, u"save", wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer6.Add( self.m_button5, 1, wx.ALL, 5 )
        bSizer1.Add( bSizer6, 0, wx.EXPAND, 5 )
        self.SetSizer( bSizer1 )
        self.Layout()
        self.Centre( wx.BOTH )
        # Connect Events
        self.Bind( wx.EVT_CLOSE, self.close_btn )
        self.m_button1.Bind( wx.EVT_BUTTON, self.btn_ok_evt )
        self.m_button5.Bind( wx.EVT_BUTTON, self.btn_save_evt )
    def __del__( self ):
        pass
    # Virtual event handlers, overide them in your derived class
    def btn_ok_evt( self, event ):
        self.gen(self.m_spinCtrl1.Value)
        event.Skip()
    def close_btn( self, event ):
        exit()
        event.Skip()
    def btn_save_evt( self, event ):
        # пример
        with wx.FileDialog(self, "Save csv file", wildcard="csv files (*.csv)|*.csv",
                           style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) as fileDialog:
            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return     # the user changed their mind
            # save the current contents in the file
            pathname = fileDialog.GetPath()
            try:
                with open(pathname, 'w') as csvfile:
                    writer = csv.writer(csvfile, delimiter=',',
                                            quotechar='|', quoting=csv.QUOTE_MINIMAL)
                    for i in self.tbl:
                        writer.writerow([i[0].GetLineText(0), i[1].GetLineText(0)])
            except IOError:
                wx.LogError("Cannot save current data in file '%s'." % pathname)        
        event.Skip()
    def xz(self):
        bSizer10 = wx.BoxSizer( wx.HORIZONTAL )
        m_textCtrl5 = wx.TextCtrl( 
            self.m_scrolledWindow3, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer10.Add( m_textCtrl5, 1, wx.ALL, 5 )
        m_textCtrl6 = wx.TextCtrl( 
            self.m_scrolledWindow3, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
        bSizer10.Add( m_textCtrl6, 1, wx.ALL, 5 )
        self.tbl_indx = [m_textCtrl5, m_textCtrl6]
        self.tbl.append(self.tbl_indx)
        return bSizer10
    def gen(self, need_row):
        self.bSizer9.DeleteWindows()
        self.tbl = []
        for i in range(need_row):
            self.bSizer9.Add(self.xz() , 1, wx.EXPAND, 5 )
            self.m_scrolledWindow3.SetSizer( self.bSizer9 )
            self.m_scrolledWindow3.Layout()
            self.m_scrolledWindow3.FitInside()
class MyApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        frame_1 = MyFrame(None)
        self.SetTopWindow(frame_1)
        frame_1.Show()
        return 1
if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()
зы спасибо не надо лучше https://www.python.org/psf/donations/
taxol
За скрипт премного благодарен, отписался в личку. А по поводу того, зачем это нужно… Есть около десяти операторов, они скрывают строки с ранее забитыми результатами, удаляют строки, что сбивает исходную форму, бьют непонятные данные поверх уже имеющихся и т.п. И взывать к порядочности и топить за дисциплину просто бессмысленно. Да, бывает и такое. А когда есть форма с жесткими рамками, все становится на свои места.
doza_and
taxol
они скрывают строки с ранее забитыми результатами
Чегото я не знаток эксел. Что такое скрытие строк?
Ну так цель понятна примерно, однако есть стойкое ощущение непродуманности задачи и методов достижения цели.

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

А корректность вы все равно должны достигать организационными мерами.

Например вы написали GUI. Операторы заметили что результат лежит в xlsx, им проще его редактировать. Они просто не будут запускать GUI а будут редактировать результат. Бороться можно только организационно.

Другой вариант. Операторы заполняют файлы, сдают вам. При сдаче вы запускаете скрипт валидации файлов, платите только за прошедшие валидацию. Тут никакого GUI нет, нужен только простейший скрипт, а ваша цель будет достигнута (опять просто организационными мерами).

По форме.
На мой взгляд если количество строк надо контролировать то нельзя давать пользователю его менять. Т.е. задание числа строк избыточно.
Для таблиц вообще есть специальный контрол с которым удобнее и пользователям работать и програмисту.

Те получится нечто такое:

 !/usr/bin/env python
# -*- coding: UTF-8 -*-
import wx
import wx.grid
NROW=5
class Form(wx.Frame):
    def __init__(self, *args, **kwds):
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((600, 400))
        self.grid = wx.grid.Grid(self, wx.ID_ANY, size=(NROW, 2))
        self.grid.CreateGrid(NROW, 2)
        self.button_save = wx.Button(self, wx.ID_ANY, "save")
        self.__do_layout()
    def __do_layout(self):
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_1.Add(self.grid, 1, wx.EXPAND, 0)
        sizer_1.Add(self.button_save, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
class MyApp(wx.App):
    def OnInit(self):
        self.frame = Form(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()
AD0DE412
ну вот и зубры подтянулись а не школота какаята :)
doza_and
Для таблиц вообще есть специальный контрол с которым удобнее и поьзователям работать и програмисту.
конечно певым делом подумалось про …

оно и удобней и производительней и без велосипедов но …
taxol
вносит в поле ввода
в общем все по ТЗ
зы doza_and вы в ручную код писали или вычищали код после конструктора
ззы taxol у вас с концепцией как то не очень эт правда … например можно и веб, гит итд в общем есть где подумать главное что бы это не было оверкиллом
doza_and
AD0DE412
doza_and вы в ручную код писали или вычищали код после конструктора
Это вопрос?
Если да, то обычно получается в конструкторе прикинуть концепцию, а потом оно ручками лучше, покомпактнее пишется. Но это для серьезных проектов, которые надо поддерживать потом. Такой код как здесь можно и в конструкторе накидать.
taxol
Всем большое спасибо за содействие! Тут лички нет, по донату отписался на почту. Скажите, можно ли на базе предложенного AD0DE412 алгоритма вносить данные не в каждую ячейку, а вставлять сразу массивом? Т.е. скопировали ячейки с A1 по B25 и вставили в форму? Чтобы не тратить время на написание нового скрипта, хотя бы натолкните на мысль.
А за нерадивость в описании ТЗ прошу прощения. Впредь такого не повторится.
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