PyQt QToolBar with scrollbar - scroll

I need to create a toolbar (on the left side for example) that will contain many buttons. On default if overall height of all buttons is greater than the hight of toolbar these surplus buttons will be hidden. And I want to make this toolbar show all buttons and allow me to scroll down to see the rest. I couldn't find anything usefull on the web so far. Any ideas?

You should be able to stick the QToolBar inside a QScrollArea.
toolbar = QtGui.QToolBar()
toolbar.setOrientation(QtCore.Qt.Vertical)
for i in range(20):
toolbar.addAction('Action{0}'.format(i))
scroll_area = QtGui.QScrollArea()
scroll_area.setWidget(toolbar)

For anyone interested here is the solution:
Thanks to #Brendan Abel's answer I've came up with an idea. What I did is I've created my toolbar the same way I did before. Then I've added all my widgets (that previously were in this toolbar) to the new QWidget with QVBoxLayout. Then I've created a QScrollArea and set my recently-created-widget as a child widget of this scroll area. And finally I've added my ScrollArea to the Toolbar using addWidget().
class LeftToolbar(QtGui.QToolBar):
def __init__(self, *args):
QToolBar.__init__(self, *args)
self.setFloatable(False)
self.setMovable(False)
self.scroll_widget = QtGui.QWidget(self)
self.scroll_layout = QtGui.QVBoxLayout()
self.scroll_widget.setLayout(self.scroll_layout)
# Add your toolbar widgets here
self.ExampleWidget1 = QtGui.QLabel(self)
self.ExampleWidget1.setText("Example Text1")
self.scroll_layout.addWidget(self.ExampleWidget1)
self.ExampleWidget2 = QtGui.QLabel(self)
self.ExampleWidget2.setText("Example Text2")
self.scroll_layout.addWidget(self.ExampleWidget2)
# Create QScrollArea
self.scroll_area = QtGui.QScrollArea()
self.scroll_area.setWidget(self.scroll_widget)
self.addWidget(self.scroll_area)
# Create object LeftToolbar in your main window
self.LeftToolbar = LeftToolbar()
self.addToolBar(Qt.LeftToolBarArea, self.LeftToolbar)

Related

How can I align items in menu bar from right to left with using python 3 and tkinter module?

I'm using python 3 and tkinter module for creating a GUI. I need to create a menu bar and align items on it from right to left (I want to use that with Persian language so I need to align my menu items from right to left), now I have used from this code but it didn't aligned file and edit items from right to left and they still align from left to right in the menubar. How can I deal with it?
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Create Menu bar and items')
root.geometry('300x300+100+50')
root.option_add('*tearOff', False)
menubar = Menu(root)
root.config(menu = menubar)
file = Menu(menubar)
edit = Menu(menubar)
menubar.add_cascade(menu = file, label = 'فایل',compound = RIGHT)
menubar.add_cascade(menu = edit, label = 'ویرایش',compound = RIGHT)
Use a simple trick, create a blank menu between the itens ;-)
blankmenu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="".ljust(130), menu=blankmenu)
I don't believe you can do what you want. I've not used Tkinter with a right-to-left language so I can't say for sure, but you're limited to what the OS supports for menubars. Tkinter gives you no control over where items are placed on a menubar, other than the relative order.

add a scrollbar to a window in LablGtk2

I want to add a scrollbar to a window in LablGtk2.
I wrote as below.
let w = GWindow.window
~width:width
~height:height
~allow_grow:true
~allow_shrink:true
~decorated:true
() in
ignore(GRange.scrollbar `HORIZONTAL ~packing:w#add ~show:true ());
However, a window(w in the code) did't show a scrollbar.
How can I make a scrollbar?
Use scrolled_window from GBin module.

How to partially display Navigation Drawer

Normally in Navigation Drawer when we click on the top left corner icon the Navigation drawer will be opened as shown in the screen1.
I need to display Navigation drawer partially as shown in the below screen 2 while the screen(Activity) is launched initially without firing any event.
Can anyone please help me.
Thanks
Ravi
set the width for ListView dynamically...
mDrawerLayout = (DrawerLayout) view.findViewById(R.id.drawer_layout);
mDrawerList = (ListView) view.findViewById(R.id.top_sectionlist);
int width = getResources().getDisplayMetrics().widthPixels/2;
DrawerLayout.LayoutParams params = (android.support.v4.widget.DrawerLayout.LayoutParams) mDrawerList.getLayoutParams();
params.width = width;
mDrawerList.setLayoutParams(params);

qwidget.render drawing with offset in QStyledItemDelegate

I'm trying to create a delegate to draw custom widgets as elements in a listview on icon mode. I have it more or less working but I can't get the widgets to draw in the right place, it seems they are getting drawn considering (0,0) the origin on the main window not the origin of the list view. What do I need to pass to render the widget on the right place? I know I can pass an offset... how can I calculate the offset between the main window and the listview?
This is my paint method on my delegate (derived from QStyledItemDelegate)
def paint(self, painter, option, index):
painter.save()
if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.highlight());
model = index.model()
myWidget = model.listdata[index.row()]
myWidget.setGeometry(option.rect)
myWidget.render(painter, option.rect.topLeft() )
painter.restore()
Thanks
/J
In case this is useful for someone else I'll post my solution...
I don't know if this is the best way of doing it, but I'm calculating the offset by mapping the orgin of my parent to the main window:
offset = self._parent.mapTo(self._mainWindow, QPoint(0,0))
myWidget.render(painter, option.rect.topLeft() + offset)
It works, so I'll use it until I find a better way for doing this.
You can render your Widget into a temporary pixmap and then draw the pixmap instead. That solves the shift issue:
def paint(self, painter, option, index):
pic = QPixmap( option.rect.width(), option.rect.height() )
w = ItemWidget()
w.setGeometry( option.rect )
w.render(pic)
painter.drawPixmap( option.rect, pic )
I use another alternative method, and it works.
painter.translate(option.rect.topLeft())
myWidget.render(painter, QtCore.QPoint(0, 0))

Python 3.1 Tkinter layout help. I am close, please help me finish this

I am using Python 3.1 by the way.
I am trying to build a simple GUI using Tkinter - label, text entry field, button on the first row and editable text area with scrollbar to the right and on the bottom of it - on the second row. Please help me fix up the layout. What I have below does not quite work. If I have to use a grid, I will. I wish to keep the code very simple - I want to "sell" Python to some of my coworkers. So, I want to get a somewhat decent look and feel. Suggest better padding if you do not mind. Also, if my variable names, etc. seem weird, then please make a note.
At the same time I want to pretend that this is a throw-away script which I have not spent much time on. Since I am asking for your help, it ain't so, but they do not need to know ;). So, I do not want to introduce fancy code to create nice borders, etc. I just want something that is visually appealing, clean and simple. If I do not, then my presentation will not achieve its goal.
Thank you, my code is below:
class App:
def __init__(self, parent):
frame = Frame(parent)
self.__setup_gui(frame) # Call Helper
frame.pack(padx=15, pady=15)
parent.title('To be changed')
def __setup_gui(self, frame):
# First Row
self.cs_label = Label(frame, text='Change Set: ')
self.cs_label.pack(side=LEFT, padx=10, pady=10)
self.cs_val = Entry(frame, width=10)
self.cs_val.pack(side=LEFT, padx=10, pady=10)
self.get_button = Button(frame, text='Get', command=self.get_content)
self.get_button.pack(side=LEFT, padx=10, pady=10)
# Text area and scrollbar
self.text_area = Text(frame, height=10, width=50, background='white')
# Put a scroll bar in the frame
scroll = Scrollbar(frame)
self.text_area.configure(yscrollcommand=scroll.set)
self.text_area.pack(side=TOP)
scroll.pack(side=RIGHT,fill=Y)
self.clipboard_var = IntVar()
self.notepad_var = IntVar()
def get_content(self):
print(self.clipboard_var.get())
print(self.notepad_var.get())
###################################################################################################
if __name__ == '__main__':
root = Tk()
app = App(root)
root.mainloop()
You definitely want the grid manager -- Pack only works for a vertical or horizontal stackup by itself. You can use multiple frames to work around it, but I find it's easier to expand a GUI if you just do it with Grid to start.
Here's what I've worked up real quick based what you said and the code. I reduced/removed the padding -- it looked huge for me -- and I set up two scrollbars, in a subframe to make the padding work out more easily. Note that to make the horizontal scrollbar useful your Text area needs to have wrap=NONE; otherwise you might as well use the easy 'ScrolledText' widget from tkinter.scrolledtext and skip the horizontal scroll bar.
I've now reframed things a bit to allow for resize, with a minimum size that shows the top buttons -- see the uses of minsize and row/columnconfigure.
BTW, it looks like your variables aren't being pulled from anywhere -- is that intentional?
from tkinter import *
class App:
def __init__(self, parent):
self.__setup_gui(parent) # Call Helper
parent.title('To be changed')
def __setup_gui(self, parent):
# First Row
self.rowframe = Frame(parent)
self.rowframe.grid()
self.cs_label = Label(self.rowframe, text='Change Set: ')
self.cs_label.grid(row=0, column=0, padx=2, pady=2)
self.cs_val = Entry(self.rowframe, width=10)
self.cs_val.grid(row=0, column=1, padx=2, pady=2)
self.get_button = Button(self.rowframe, text='Get', command=self.get_content)
self.get_button.grid(row=0, column=2, padx=2, pady=2)
parent.update_idletasks()
parent.minsize(width=self.rowframe.winfo_width(), height=self.rowframe.winfo_height())
# Text area and scrollbars
self.textframe = Frame(parent)
self.textframe.grid(row=1, columnspan=2, padx=2, pady=2, sticky=N+S+E+W)
self.hscroll = Scrollbar(self.textframe, orient=HORIZONTAL)
self.vscroll = Scrollbar(self.textframe)
self.text_area = Text(self.textframe, height=10, width=50, wrap=NONE, background='white', yscrollcommand=self.vscroll.set, xscrollcommand=self.hscroll.set)
self.text_area.grid(row=0, column=0, sticky=N+S+E+W)
self.hscroll.config(command=self.text_area.xview)
self.hscroll.grid(row=1, column=0, sticky=E+W)
self.vscroll.config(command=self.text_area.yview)
self.vscroll.grid(row=0, column=1, sticky=N+S)
# Row 0 defaults to 0
parent.rowconfigure(1, weight=1)
parent.columnconfigure(1, weight=1)
# Textarea setup
self.textframe.rowconfigure(0, weight=1)
self.textframe.columnconfigure(0, weight=1)
self.clipboard_var = IntVar()
self.notepad_var = IntVar()
def get_content(self):
print(self.clipboard_var.get())
print(self.notepad_var.get())
###################################################################################################
if __name__ == '__main__':
root = Tk()
app = App(root)
root.mainloop()
Now, all that said...you might get more visual appeal with PyGTK, PyQt, or wxPython, though tkinter coming "standard" is a nice feature.

Resources