Форум сайта python.su
Здравствуйте! Прошу помощи по следующей проблеме приведу код в общих чертах
root = Frame()
root.pack()
canvas = Canvas(master = root)
frame_grid = Frame(master = canvas)
в frame_grid создаю таблицу c помощью компоновщика grid(), в строке с индексом 0 размещаю заголовок таблицы
scrollbar = Scrollbar(master=root)
scrollbar(scrollregion = (0,21,100,200) - задаю scroll со второй frame_grid строки до последней
в результате шапка таблицы(строка с индексом 0 ) поднимается вверх и при отображении виджета ее невидно получается таблицу с данными видно а шапку нет??? подскажите в каком направлении идти
создавать шапку в отдельном фрейме или есть другой путь решения данной проблемы???
Офлайн
Фреймов нагородили. Жуть root - не фрейм!!! Лучше так не делать.
Я посоветовал бы просто шапку расположить выше canvas по центру. И все. Она прокручиваться не будет. Это самый наитивный и простой способ. Да и выглядеть код будет нормально и красиво.
Есть еще способ с использование create_window, но вышеприведенный проще в разы и понятнее.
P.S. Никогда не делайте!!!
from tkinter import *
Офлайн
4kpt_IIЯ хочу написать виджет-my_grid который легко можно встраивать в любой другой виджет и передавать ему данные из базы данных. Поэтому я использую за основу Фрейм к которому прикрепляю скролы и canvas сам grid думаю переписать и реализовать непосредственно в canvas - вроде теперь уже понятно как это сделать, а шапку как вы предлагаете делать буду выше canvas но опять получается надо использовать Frame?! Если есть более продвинутые решения буду благодарен если поделитесь опытом!
Фреймов нагородили. Жуть root - не фрейм!!! Лучше так не делать.Я посоветовал бы просто шапку расположить выше canvas по центру. И все. Она прокручиваться не будет. Это самый наитивный и простой способ. Да и выглядеть код будет нормально и красиво.Есть еще способ с использование create_window, но вышеприведенный проще в разы и понятнее.P.S. Никогда не делайте!!!
Офлайн
tisul
Я хочу написать виджет-my_grid который легко можно встраивать в любой другой виджет и передавать ему данные из базы данных
tisul
Поэтому я использую за основу Фрейм к которому прикрепляю скролы и canvas сам grid думаю переписать и реализовать непосредственно в canvas
Офлайн
Наконец то я смог сделать скроллируемую таблицу с шапкой по “x” и “у” но есть вопрос
как определить высоту и ширину видимой таблицы при уменьшении основного виджета.
Таблица размер 600 на 600 - основной виджет? в который вложена таблица 400 на 400? есть ли способ быстрого и точного определения размера 400 на 400 или его придется вычислять опираясь на размеры основного виджета от его размеров отнимать размер шапки и размеры скроллов?
Офлайн
Размер определять не обязательно.
Для этого у менеджеров геометрии есть свойство, которое описывает растягивание вложенного объекта по горизонтали и вертикали. У каждого менеджера это свойство свое. Не его только у менеджера place. Но там заложен механизм относительных величин.
Каким менеджером Вы пользуетесь. Я подскажу.
Офлайн
пример ниже приведен чтобы можно было понять что я делаю(действительный код очень длинный думаю в нем разбираться не очень охота будет)
fr = Frame()
scr_y = tk.Scrollbar(fr,orient='vertical')
scr_x = tk.Scrollbar(fr,orient='horizontal')
canvas_header = Canvas(fr)
canvas_body = Canvas(fr)
scr_y.pack()
scr_x.pack()
canvas_header.pack()
canvas_body.pack()
в canvas_header размещаю шапку таблицы, строю менеджером grid
в canvas_body размещаю тело таблицы, строю менеджером grid
при уменьшении размеров fr мне нужно вычислить видимую область canvas_body
в таблице я сделал при нажатии клавиш управления “вверх” и “вниз” подсвечивание строк (переход по строкам) и когда я дохожу до последней видимой строки мне необходимо поднять таблицу вверх, чтобы увидеть следующую строку, для этого я и хочу знать видимую область canvas_body, зная ее я могу разделить высоту видимой области на высоту строки таблицы, тем самым я могу отследить когда необходимо поднимать или опускать таблицу. Вообще я все это дело реализую при помощи ООП, но код пишу кратко чтобы была ясна суть. За помощь благодарен очень - 4kpt_II.
Офлайн
Давайте начнем с самого начала.
1. Что у Вас внутри второго Canvas? Тело таблицы состоит из чего? Если это списки (Listbox), то это одно дело, если это поля ввода Entry, то вообще другое.
2. Зачем для подписи использовать Canvas, если можно было просто Label?
3. Что в итоге хотите получить? Для большего понимания желательно скинуть скрин.
Без ответов на эти вопросы я не смогу Вам помочь ибо сумбурно очень выражаетесь. Вы поставили сообщении выше уже как минимум три разных вопроса. Давайте решать проблемы по-очереди
P.S.
tisul
при помощи ООП
Отредактировано 4kpt_II (Май 27, 2014 21:50:22)
Офлайн
Картинки выложил на кибер диск в zip иначе не хочет их загружать
Your text to link here…
import tkinter as tk import connectiondatabase as con class Grid_Frame(tk.Frame): def __init__(self,master=None,cnf={},**kw): tk.Frame.__init__(self,master,cnf,**kw) self.propagate(flag=False) self.canvas_header = tk.Canvas(self,bg = 'blue') self.canvas_body = tk.Canvas(self,bg = 'green') self.canvas_body.bind_all("<MouseWheel>", self._on_mousewheel) self.frame_header = tk.Frame(self.canvas_header) self.frame_body = tk.Frame(self.canvas_body,bg = 'red') self.count = 0 self.select_row = 0 self.bind_all('<KeyPress>',self.key_press) self.coordinates_header = (0,0,0,0) self.list_header = [] # список заголовков таблицы, элементы списка словари, где ключ visible отображать заголовок name имя заголовка self.list_header = [{'id':'id','name':'код','visible':True,'width':25,'bg':'white','height':1,'anchor':'center'}, {'id':'name','name':'Наименование','visible':True,'width':50,'bg':'white','height':1,'anchor':'center'}] self.dict_column = {'id':0,'name':1} def create_grid(self,connection): scr_y = tk.Scrollbar(self,orient='vertical') scr_x = tk.Scrollbar(self,orient='horizontal') scr_y.pack(side='right',fill='y') scr_x.pack(side='bottom',fill='x') self.canvas_header.pack(fill='x',side='top') self.frame_header.pack(fill='x',side='top') self.canvas_body.pack(expand='yes',fill='both',side='top') self.frame_body.pack(fill='x',side='top',anchor='center') self.canvas_body.configure(yscrollcommand=scr_y.set) self.canvas_header.configure(xscrollcommand=scr_x.set) scr_y.configure(command=self.canvas_body.yview) scr_x.configure(command=self._xview) self.create_header(self.list_header) # создаем шапку таблицы self.fill_grid(connection) # заполняем таблицу def _xview(self,*arg): if arg[0] == 'scroll': self.canvas_body.xview_scroll(arg[1], arg[2]) self.canvas_header.xview_scroll(arg[1], arg[2]) elif arg[0] == 'moveto': self.canvas_body.xview_moveto(arg[1]) self.canvas_header.xview_moveto(arg[1]) def _on_mousewheel(self,event): self.canvas_body.yview_scroll(-1*int(event.delta/120), "units")#??????? def create_header(self,list_header): column = 0 for field in list_header: if field['visible']!=True: continue lb = tk.Label(self.frame_header,text=field['name'],relief='raised',width=field['width'] ,bg=field['bg'],height=field['height']) lb.grid(row=0,column=column,sticky='nsew') column +=1 self.update() self.canvas_header.create_window(0,0,anchor='nw',window=self.frame_header,tag='header') coordinates_header = self.canvas_header.bbox('all') self.canvas_header.config(scrollregion=coordinates_header,height=coordinates_header[3]) def fill_grid(self,connection): column = 0 connection.cursor.execute("select id,name from proba") for k in cn.cursor: self.list_grid.append([]) self.count +=1 for key_column in self.dict_column: index_column = self.dict_column[key_column] lb = tk.Label(self.frame_body,text=k[index_column],relief='raised',anchor='w' ,width=self.list_header[index_column]['width'] ,height = self.list_header[index_column]['height']) lb.grid(row=self.count,column=index_column,sticky='nsew') self.list_grid[self.count].append(lb) self.update() self.canvas_body.create_window(0,0,anchor='nw',window=self.frame_body,tag='header') coordinates_scrollregion = self.canvas_body.bbox('all') self.canvas_body.config(scrollregion=coordinates_scrollregion,height=coordinates_scrollregion[3]) def key_press(self,event): count = range(0,len(self.dict_column))#количество столбцов if event.keycode == 40:#клавиша управления вниз if self.select_row < self.count: if self.select_row>0 and self.select_row<self.count: for index_count in count: self.list_grid[self.select_row][index_count].configure(bg='white') self.select_row +=1 for index_count in count: self.list_grid[self.select_row][index_count].configure(bg='#8080c0') elif event.keycode == 38:# клавиша управления вверх if self.select_row >1: if self.select_row >1 : for index_count in count: self.list_grid[self.select_row][index_count].configure(bg='white') self.select_row -=1 for index_count in count: self.list_grid[self.select_row][index_count].configure(bg='#8080c0') #==================================================== if __name__ == '__main__': fr_grid = Grid_Frame(bg='blue',width=600,height=200) fr_grid.pack(expand='yes',fill='both',side="left",anchor='ne') cn = con.ConnectionDataBase('base') cn.verify_connection() if cn.flag_connection: fr_grid.create_grid(cn) tk.mainloop()
Отредактировано tisul (Май 28, 2014 09:48:09)
Офлайн
Не могу нормально протестить.
Дайте результат метода
connection.cursor.execute("select id,name from proba")
Офлайн