While building a simple GUI video downloader in python and with Glade3 I am stuck with pasting into a text entry box using an icon.
The application, and paste icon.
The python code:
# !/usr/python
import sys
import os
import subprocess as sp
try:
from gi.repository import Gtk, Gdk
except:
print('Gtk not available')
sys.exit(1)
try:
import pyGtk
pyGtk.require('2.0')
except:
pass
class VideoDownloader:
def on_mainwindow_destroy(self, object, data=None):
print "quit with cancel"
Gtk.main_quit()
def __init__(self):
self.gladefile = "lib/videodownloder.glade"
self.builder = Gtk.Builder()
self.builder.add_from_file(self.gladefile)
self.builder.connect_signals(self)
self.go = self.builder.get_object
self.window = self.go("mainwindow")
self.window.show()
self.okbtn = self.go("okbutton")
self.cancelbtn = self.go("cancelbutton")
#self.restartswitch = self.go("restartswitch")
self.contswitch = self.go("contswitch")
self.vlcswitch = self.go("vlcswitch")
self.urlentry = self.go("urlentry")
self.filechooser = self.go("filechooser")
self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
def on_urlentry_activate(self, widget):
url = self.urlentry.get_text()
print("the url is:" + url)
def on_urlentry_icon_press(self):
text = self.clipboard.set_text(self.urlentry.get_text(), -1)
print("the urlentry paste icon was clicked | 'text' ")
def on_urlentry_icon_press(self):
text = self.clipboard.wait_for_text()
print("the urlentry paste icon was clicked | 'text' ")
if text != None:
self.urlentry.set_text(text)
print(" 'text' has been pasted to the urlentry")
else:
print("No text on the clipboard")
def on_filechooser_file_activated(self, widget):
myfile = self.filechooser.get_uri()
print("the file is: " + myfile)
def on_vlcswitch_activate(self, widget):
print("VLC Switch has been activated")
def on_contswitch_activate(self, widget):
print("Continue switch has been acivated")
def on_quitbutton_clicked(self, button):
print("quit with the close button")
Gtk.main_quit()
def on_okbutton_clicked(self, button):
myfile = self.filechooser.get_uri()
url = self.urlentry.get_text()
wgetcmd = ("wget -O 'myfile ' 'url' ")
print("ok button has been clicked")
print("wget will now be run with your args: " +myfile+url)
os.system(wgetcmd)
if __name__ == "__main__":
print("videodownloader is running")
notify = os.system("notify-send --expire-time=5000 --icon='img/vid-down-logo.png' --app-name=VideoDownloader 'VideoDownloader' 'The VideoDownloader app is now running and ready!'")
notify
main = VideoDownloader()
Gtk.main()
print("videodownloader has stopped running")
When I run the code it mostly works but when I click the paste icon I get an error:
TypeError: on_urlentry_icon_press() takes exactly 1 argument (4 given)
I am fairly new to python and glade so I am probably making an elementary mistake but I do not know what is wrong and what the error means. I have searched but found only advice that didn't help.
Such as this..
Any suggestions on how to fix this please?
Your current on_urlentry_icon_press method only takes the self argument but it should take more than one because it is connected to the icon-press signal.
In the documentation you can see that it takes:
entry (a reference to the Gtk.Entry)
position (whether it is the primary or secondary icon)
event (e.g. whether it was a double click)
So it should look like this:
def on_urlentry_icon_press(self, entry, position, event):
print('urlentry icon clicked')
Related
I would like to create a QPushButton that stays pressed until the user presses it again. I know I can use setCheckable for this. But I am unsure how to create a proper signal for the button that is triggered when the button changes state, pressed and unpressed. Toggled seems to work, but it is sending 3 arguments. I am unsure what the 3 args being sent are in my example.
import maya.cmds as cmds
import os
import maya.OpenMayaUI as mui
from PySide2 import QtWidgets,QtCore,QtGui
import shiboken2
class widget():
def __init__(self):
self.objs = ["box_1","box_2","box_3"]
def label_event(self,text):
print("this is the pressed button's label", text)
def populate(self):
for obj in self.objs:
label = QtWidgets.QPushButton(obj)
label.setCheckable(True)
label.toggled.connect(partial(self.label_event, obj))
self.vertical_layout_main.addWidget(label)
def palette_ui(self):
windowName = "palette"
if cmds.window(windowName,exists = True):
cmds.deleteUI(windowName, wnd = True)
pointer = mui.MQtUtil.mainWindow()
parent = shiboken2.wrapInstance(long(pointer),QtWidgets.QWidget)
self.window = QtWidgets.QMainWindow(parent)
self.window.setObjectName(windowName)
self.window.setWindowTitle(windowName)
self.mainWidget = QtWidgets.QWidget()
self.window.setCentralWidget(self.mainWidget)
self.vertical_layout_main = QtWidgets.QVBoxLayout(self.mainWidget)
self.populate()
self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.window.show()
lg = widget()
lg.palette_ui()
You have to activate the property with setCheckable(True) and use the toggled signal:
import sys
from PySide import QtGui
def function(checked):
print("is checked?: ", checked)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
button = QtGui.QPushButton("press me")
button.setCheckable(True)
button.toggled.connect(function)
button.show()
sys.exit(app.exec_())
Update:
Do not use object is a reserved word, on the other hand the signal passes the parameter checked, if you want to pass another parameter you must also place it in the function:
def label_event(self, text, checked): # <---
print("this is the pressed button's label", text, checked)
def populate(self):
for obj in self.objects:
label = QtWidgets.QPushButton(obj)
label.setCheckable(True)
label.toggled.connect(partial(self.label_event, obj))
self.vertical_layout_main.addWidget(label)
I have made a script extension for a programm called Nuke which opens a dialog with lineedit and allows the user to enter a label. However the script only executes setLabel() by pressing enter when there are only ascii characters in the lineedit.
text() returns unicode and Nuke has no problem with special characters like äöü in labels if you do it through the normal ui
Here is my code:
# -*- coding: utf-8 -*-
from PySide2 import QtCore, QtGui, QtWidgets
import nuke
import sys
import os
class setLabelTool(QtWidgets.QDialog):
def __init__(self, node):
self.n = node
super(setLabelTool, self).__init__()
self.setObjectName("Dialog")
self.setWindowTitle("Test")
self.setFixedSize(199, 43)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
self.lineEdit = QtWidgets.QLineEdit(self)
self.lineEdit.setGeometry(QtCore.QRect(10, 10, 181, 25))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit.setFocusPolicy(QtCore.Qt.StrongFocus)
self.lineEdit.setAlignment(QtCore.Qt.AlignHCenter)
currentlabel = self.n['label'].value()
if len(currentlabel) == 0:
self.lineEdit.setPlaceholderText("Set node label")
else:
self.lineEdit.setText(currentlabel)
self.lineEdit.selectAll()
self.lineEdit.returnPressed.connect(self.setLabel)
def setLabel(self):
label = self.lineEdit.text()
self.n['label'].setValue(label)
print ("Node: " + self.n['name'].value() + " labeled " + label)
self.close()
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
print "Exit setLabelTool"
self.close()
def showLabelTool():
n = nuke.selectedNodes()[-1]
if n != None:
Tool = setLabelTool(n)
Tool.exec_()
else:
print "Error in showLabelTool()"
I had the same problem yesterday.
text() returns of type unicode and your method needs a string object, to convert just use encode('utf-8')
This might be a bit out of context, but there's easier ways to change the label for a node in Nuke using getInput if that's what you're trying to accomplish:
new_label = nuke.getInput("enter label")
nuke.selectedNode()['label'].setValue(new_label)
I got a little issue concerning wxPython and the system tray.
Well, all I use is the system tray and I want to have it call a function right after the system tray got drawn, but EVT_PAINT seems to have no effect on the tray for me.
Anyways, here is my code:
#!/usr/bin/python2
import wxversion
wxversion.select('2.8')
import pynotify,subprocess,wx,os,json
#config
TRAY_TOOLTIP = 'Backups'
PROG_DIR = os.path.dirname(os.path.realpath(__file__))
class Config:
def __init__(self):
self.readFile()
def readFile(self):
jsons = ''
searchingJson = True
f = open(PROG_DIR+'/config.json')
lines = f.readlines()
f.close()
self.json = json.loads(lines)
pynotify.init("Backups")
def backup():
sysTray.set_icon(PROG_DIR+'/loading.png')
pynotify.Notification("Backups","Starting Backup",PROG_DIR+'/backup.png').show()
if subprocess.call(["rsync","-a",config.json['backup_dir'],"--exclude",".*",config.json['remote_dir']]):
pynotify.Notification("Backups","Backup Failed",PROG_DIR+'/backup.png').show()
else:
pynotify.Notification("Backups","Backup complete!",PROG_DIR+'/backup.png').show()
sysTray.set_icon(PROG_DIR+'/backup.png')
def create_menu_item(menu,label,func):
item = wx.MenuItem(menu,-1,label)
menu.Bind(wx.EVT_MENU,func,id=item.GetId())
menu.AppendItem(item)
return item
class TaskBarIcon(wx.TaskBarIcon):
def __init__(self):
super(TaskBarIcon,self).__init__()
self.set_icon(PROG_DIR+'/backup.png')
self.Bind(wx.EVT_PAINT,self.initial_backup)
def CreatePopupMenu(self):
menu = wx.Menu()
create_menu_item(menu,'Start Backup',self.on_backup)
menu.AppendSeparator()
create_menu_item(menu,'Exit',self.on_exit)
return menu
def set_icon(self,path):
icon = wx.IconFromBitmap(wx.Bitmap(path))
self.SetIcon(icon,TRAY_TOOLTIP)
def on_exit(self,event):
wx.CallAfter(self.Destroy)
def on_backup(self,event):
backup()
def initial_backup(self,event):
print 'test'
def main():
app = wx.App(False)
sysTray = TaskBarIcon()
app.MainLoop()
if __name__ == '__main__':
main()
Nothing gets printed to the terminal.
Thanks for help!
Is there a way to get notified of clipboard change in KDE/GNOME via D-Bus? How can I capture/eavesdrop/subscribe to clipboard selection (esp. in PyGTK)? I have gtk.Clipboard.wait_for_text() method available but it returns clipboard contents immediately while I need to invoke it only when clipboard changes.
Got that pretty much here: python and gtk3 clipboard onChange
The core of the problem is:
self.clipboard = gtk.Clipboard()
self.clipboard.connect("owner-change", self.renderText)
It's black magic to me where this owner-change signal came from or how to find what signal is responsible for particular event (understood as gui phenomena) but it works:
#!/usr/bin/env python
import gtk, glib
class ClipboardParse:
def __init__(self):
window = gtk.Window()
window.set_title("example")
window.resize(600,400)
box = gtk.HBox(homogeneous = True, spacing = 2)
self.buf = gtk.TextBuffer()
textInput = gtk.TextView(self.buf)
self.lbl = gtk.Label()
box.add(self.lbl)
window.add(box)
window.connect("destroy", gtk.main_quit)
window.show_all()
self.clipboard = gtk.Clipboard()
self.clipboard.connect("owner-change", self.renderText)
def renderText(self, clipboard, event):
print 'C {0} | E {1}'.format(clipboard, event)
txt = self.clipboard.wait_for_text()
self.lbl.set_text(txt)
print txt
return False
if __name__ == '__main__':
ClipboardParse()
gtk.main()
I made this Python script:
from gi.repository import Gtk, Gdk, GdkX11, Wnck
from subprocess import PIPE, Popen
class WindowError(Exception):
pass
def undecorate(aWindow):
gdkdis = GdkX11.X11Display.get_default()
gdkwin = GdkX11.X11Window.foreign_new_for_display(gdkdis, aWindow.get_xid())
gdkwin.set_decorations(Gdk.WMDecoration.BORDER)
def dropdown(aTitle):
Gtk.main_iteration()
screen = Wnck.Screen.get_default()
screen.force_update()
for window in screen.get_windows():
if window.get_name() == aTitle:
timestamp = Gtk.get_current_event_time()
undecorate(window)
window.set_skip_pager(True)
window.set_skip_tasklist(True)
window.stick()
window.pin()
window.maximize_horizontally()
window.set_geometry(Wnck.WindowGravity.STATIC,
Wnck.WindowMoveResizeMask.Y,
0, 0, -1, -1)
window.activate(timestamp)
window.unminimize(timestamp)
break
else:
raise WindowError('Window with title "{}" not found'.format(aTitle))
def getActive():
Gtk.main_iteration()
screen = Wnck.Screen.get_default()
screen.force_update()
return screen.get_active_window()
def main():
active = getActive()
if active.get_name() == 'Dropdown Terminal':
if active.is_minimized():
dropdown('Dropdown Terminal')
else:
active.minimize()
return
else:
try:
dropdown('Dropdown Terminal')
except WindowError:
Popen(['roxterm', '--profile=Dropdown'], stdout=PIPE, stderr=PIPE)
dropdown('Dropdown Terminal')
if __name__ == "__main__":
main()
What it does is it makes roxterm act like Guake. The only problem I have with it is when I Popen a new roxterm instance and move the window to (0,0) right after, the final y-position of the window is a few visible pixels down. I used the set_geometry function in the wnck library to do this. Any ideas on how to fix it? Thanks.
Oops, forgot to mention that I solved this issue. I changed some stuff in the code, but I think using GdkWindow to reposition instead of Wnck fixed the positioning problem. This version keeps the dropdown terminal open until the hotkey is pressed again. BTW, I mapped the hotkey to this script by adding a custom hotkey in Gnome's keyboard preferences.
from gi.repository import Gtk, Gdk, GdkX11, Wnck
from subprocess import PIPE, Popen
class WindowError(Exception):
pass
def getScreen():
Gtk.main_iteration()
screen = Wnck.Screen.get_default()
screen.force_update()
return screen
def getGDKWindow(aWindow):
gdkdisplay = GdkX11.X11Display.get_default()
gdkwindow = GdkX11.X11Window.foreign_new_for_display(gdkdisplay, aWindow.get_xid())
return gdkwindow
def getWindow(aTitle):
screen = getScreen()
active = screen.get_active_window()
if active.get_name() == aTitle:
return active
for window in screen.get_windows():
if window.get_name() == aTitle:
return window
return None
def adjust(aWindow):
gdkwindow = getGDKWindow(aWindow)
gdkwindow.set_decorations(Gdk.WMDecoration.BORDER)
gdkwindow.move(0,0)
aWindow.set_skip_pager(True)
aWindow.set_skip_tasklist(True)
aWindow.maximize_horizontally()
aWindow.stick()
aWindow.make_above()
def onWindowOpen(aScreen, aWindow, aData):
if aWindow.get_name() == aData:
adjust(aWindow)
Gtk.main_quit()
def main():
timestamp = Gtk.get_current_event_time()
window = getWindow('Dropdown Terminal')
if window:
if window.is_minimized():
window.activate(timestamp)
window.unminimize(timestamp)
else:
window.minimize()
else:
Popen(['roxterm', '--separate', '--profile=Dropdown', '--directory=.'])
getScreen().connect('window-opened', onWindowOpen, 'Dropdown Terminal')
Gtk.main()
if __name__ == "__main__":
main()