Why does this pygtk TextView refuse to wrap? - python

I have a textview inside a scrolledwindow that refuses to wrap to words/chars/wordschars no matter how I set the wrap mode. It simply extends the size of itself and its containers as it pleases. Here's an example:
import gtk
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(256,256)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
view = gtk.TextView()
view.set_wrap_mode(gtk.WRAP_CHAR)
scroll.add(view)
window.add(scroll)
window.show_all()
gtk.main()
How can I make it wrap? If it matters, I need the parent window to be resizeable by the user, just not the text.

You need to set the size request on the TextView's container (which is scroll in your example), not the Window or the TextView itself.
Try the following:
import gtk
if __name__ == "__main__":
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
scroll = gtk.ScrolledWindow()
scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
view = gtk.TextView()
view.set_wrap_mode(gtk.WRAP_CHAR)
scroll.set_size_request(256, 256)
scroll.add(view)
window.add(scroll)
window.show_all()
gtk.main()

I just ran your code and word wrapping seems to be working fine. What are you running it on? I'm using PyGTK 2.22 on Ubuntu 11.04.

Related

Python Gtk 3.0: How to grab focus inside Notebook

I'm trying to set the focus to an Entry input field. If I put it inside a Box, I can set the focus via the grab_focus method. But if the Entry is inside a Notebook, it is not focused.
Example code:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Simple Notebook Example")
self.set_border_width(3)
self.notebook = Gtk.Notebook()
self.add(self.notebook)
self.page1 = Gtk.Box()
self.page1.set_border_width(10)
self.page1.add(Gtk.Label(label="Default Page!"))
self.notebook.append_page(self.page1, Gtk.Label(label="Plain Title"))
self.note = Gtk.Entry()
self.note.set_activates_default(True)
self.note.set_text("")
self.page1.add(self.note)
self.page2 = Gtk.Box()
self.page2.set_border_width(10)
self.page2.add(Gtk.Label(label="A page with an image for a Title."))
self.notebook.append_page(
self.page2, Gtk.Image.new_from_icon_name("help-about", Gtk.IconSize.MENU)
)
self.note.grab_focus() # does not work
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
How can I focus self.note inside the notebook?
Thanks for any help!
As it turns out, you can only grab focus to visible widgets.
Calling grab_focus after show_all makes the example work:
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
win.note.grab_focus()
Gtk.main()

Why does the destroy signal not reach the children of a Gtk.ScrolledWindow?

Please consider this python code for a simple GTK window:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def on_destroy(widget):
print("Destroying {}".format(widget))
def on_click(button, scroll):
scroll.destroy()
scroll = Gtk.ScrolledWindow()
scroll.connect("destroy", on_destroy)
button = Gtk.Button.new_with_label("Self-destruct")
scroll.add(button)
button.connect("destroy", on_destroy)
button.connect("clicked", on_click, scroll)
window = Gtk.Window()
window.add(scroll)
window.connect("destroy", Gtk.main_quit)
window.set_size_request(200, 75)
window.show_all()
Gtk.main()
When pressing the button, I would expect to get two output lines reporting that the ScrolledWindow and the button got destroyed. In reality I only get one line reporting about the ScrolledWindow, the destroy signal never reaches the button. If I replace the ScrolledWindow with a normal Box, the destroy signal reaches the button. Why is this?
I really can't tell you much more than this code which does delete the button. Hopefully, you can adapt it to your needs. It does seem like the button unattaches itself from the Viewport and attaches itself to nothing, because the button's destroy handler runs on app shutdown, and causes weird errors. It would be interesting to post this on the Gtk mailing list for any other thoughts.
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def on_destroy(widget, viewport):
print("Destroying {}".format(widget))
viewport.get_child().destroy()
def on_button_destroy(widget):
print("Destroying button {}".format(widget))
def on_click(button):
scroll = button.get_parent().get_parent()
scroll.destroy()
scroll = Gtk.ScrolledWindow()
button = Gtk.Button.new_with_label("Self-destruct")
scroll.add(button)
viewport = button.get_parent()
button.connect("destroy", on_button_destroy)
scroll.connect("destroy", on_destroy, viewport)
button.connect("clicked", on_click)
window = Gtk.Window()
window.add(scroll)
window.connect("destroy", Gtk.main_quit)
window.set_size_request(200, 75)
window.show_all()
Gtk.main()

PyGTK, Threads and WebKit

In my PyGTK app, on button click I need to:
Fetch some html (can take some time)
Show it in new window
While fetching html, I want to keep GUI responsive, so I decided to do it in separate thread. I use WebKit to render html.
The problem is I get empty page in WebView when it is in separated thread.
This works:
import gtk
import webkit
webView = webkit.WebView()
webView.load_html_string('<h1>Hello Mars</h1>', 'file:///')
window = gtk.Window()
window.add(webView)
window.show_all()
gtk.mainloop()
This does not work, produces empty window:
import gtk
import webkit
import threading
def show_html():
webView = webkit.WebView()
webView.load_html_string('<h1>Hello Mars</h1>', 'file:///')
window = gtk.Window()
window.add(webView)
window.show_all()
thread = threading.Thread(target=show_html)
thread.setDaemon(True)
thread.start()
gtk.mainloop()
Is it because webkit is not thread-safe. Is there any workaround for this?
According to my experience, one of the things that sometimes doesn't work as you expect with gtk is the update of widgets in separate threads.
To workaround this problem, you can work with the data in threads, and use glib.idle_add to schedule the update of the widget in the main thread once the data has been processed.
The following code is an updated version of your example that works for me (the time.sleep is used to simulate the delay in getting the html in a real scenario):
import gtk, glib
import webkit
import threading
import time
# Use threads
gtk.gdk.threads_init()
class App(object):
def __init__(self):
window = gtk.Window()
webView = webkit.WebView()
window.add(webView)
window.show_all()
self.window = window
self.webView = webView
def run(self):
gtk.main()
def show_html(self):
# Get your html string
time.sleep(3)
html_str = '<h1>Hello Mars</h1>'
# Update widget in main thread
glib.idle_add(self.webView.load_html_string,
html_str, 'file:///')
app = App()
thread = threading.Thread(target=app.show_html)
thread.start()
app.run()
gtk.main()
I don't know anything about webkit inner workings, but maybe you can try it with multiple processes.

Webkit context-menu

I have a little program with a webkit window inside (realy cutted code attached), I would disable the context-menu, but I don't know how..
I found this 'enable-default-context-menu': http://webkitgtk.org/reference/webkitgtk-WebKitWebSettings.html, but I can't make it work..
Can you help me?
TNK
#!/usr/bin/env python
import gtk
import webkit
from webkit import WebView
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("destroy", gtk.main_quit)
browser = webkit.WebView()
browser.open("http://www.stackoverflow.com")
scroller = gtk.ScrolledWindow()
scroller.add(browser)
window.add(scroller)
settings = browser.get_settings()
settings.set_property('enable-default-context-menu', False)
window.show_all()
gtk.main()
Going by the seat of my pants here, but try:
#!/usr/bin/env python
import gtk
import webkit
browser = webkit.WebView()
settings = browser.get_settings()
settings.set_property('enable-default-context-menu', False)
browser.set_settings(settings) # Push the changed settings back!
scroller = gtk.ScrolledWindow()
scroller.add(browser)
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.connect("destroy", gtk.main_quit)
window.add(scroller)
browser.open("http://www.stackoverflow.com")
window.show_all()
gtk.main()
I tried your code and it works fine for me... using pywebkit 1.1.7 (Linux Ubuntu)
What version of pywebkit do you have?
p.s. you should have edited your previous post instead of creating a new one.

How to display an image next to a menu item?

I am trying to get an image to appear next to a menu item but it isn't working.
In order to make this as simple as possible, I have created a very simple example below that highlights the problem:
import pygtk
pygtk.require('2.0')
import gtk
class MenuExample:
def __init__(self):
window = gtk.Window()
window.set_size_request(200, 100)
window.connect("delete_event", lambda w,e: gtk.main_quit())
menu = gtk.Menu()
menu_item = gtk.ImageMenuItem("Refresh")
img = gtk.image_new_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_MENU)
img.show()
menu_item.set_image(img)
menu.append(menu_item)
menu_item.show()
root_menu = gtk.MenuItem("File")
root_menu.show()
root_menu.set_submenu(menu)
vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()
menu_bar = gtk.MenuBar()
vbox.pack_start(menu_bar, False, False, 2)
menu_bar.show()
menu_bar.append(root_menu)
window.show()
def main():
gtk.main()
return 0
if __name__ == "__main__":
MenuExample()
main()
When I run the application, it shows the menu item, but it does not show the image next to it.
OS: Ubuntu 10.04 64-bit
Python version: 2.6.5
Hmmm... it turns out the answer was that my desktop theme had disabled icons for menus. (Who knows why.)
After enabling the option, the icons now show up.

Categories

Resources