FocusReason in PyQt5? - python

I noticed that when calling QtWidgets.setFocus, I get a warning in PyCharm saying that it expects a Qt.FocusReason rather than a Boolean. Indeed, the documentation for this method also states that it takes a Qt.FocusReason. But for the life of me, I can't find any information on this for PyQt5.
myPlainTextEdit.setFocus(True)
The method works perfectly fine by passing in a Boolean, but I'm wondering if this is perhaps some legacy from PyQt4, or just an anomaly? I noticed that on the PyQt Sourceforge Documentation, which seems to be for PyQt4, that it says to get FocusReason from QFocusEvent. In attempting to do this, I get another warning; Expected type 'FocusReason', got 'Type' instead. This raises a TypeError, as one might expect.
myPlainTextEdit.setFocus(QtGui.QFocusEvent.ActionAdded)
The PyQt5 documentation does not appear to contain a page for Qt.FocusReason. As this is extremely pedantic, I'm not overly concerned if there is no solution. I am interested to know what causes this. Is it possible to pass a Qt FocusReason to QtWidgets.setFocus in the first place?

There are 2 functions called setFocus() that every widget supports:
void QWidget::setFocus(Qt::FocusReason reason)
void QWidget::setFocus()
You are referring to the first. So let's analyze what you point out:
The method works perfectly fine by passing in a Boolean
It works but it does not imply that it is correct, first Qt::FocusReason is an enumeration, that is to say that each element that belongs is associated to a number:
Qt::MouseFocusReason 0 A mouse action occurred.
Qt::TabFocusReason 1 The Tab key was pressed.
Qt::BacktabFocusReason 2 A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab.
Qt::ActiveWindowFocusReason 3 The window system made this window either active or inactive.
Qt::PopupFocusReason 4 The application opened/closed a pop-up that grabbed/released the keyboard focus.
Qt::ShortcutFocusReason 5 The user typed a labels buddy shortcut
Qt::MenuBarFocusReason 6 The menu bar took focus.
Qt::OtherFocusReason 7 Another reason, usually application-specific.
so when passing a Boolean it will convert it to an integer, False to 0 and True to 1, so setFocus(True) equals setFocus(QtCore.Qt.TabFocusReason).
In attempting to do this, I get another warning; Expected type 'FocusReason', got 'Type' instead. This raises a TypeError, as one might expect.
myPlainTextEdit.setFocus(QtGui.QFocusEvent.ActionAdded)
As you realize QtGui.QFocusEvent.ActionAdded does not belong to that list, so it throws the error. You have to use the values from the previous list by changing :: by . and prefixing it with QtCore since it belongs to that submodule, for example:
myPlainTextEdit.setFocus(QtCore.Qt.MouseFocusReason)
Plus:
If you just want to establish that the widget has the focus you should call the second function:
myPlainTextEdit.setFocus()
And for clean use clearFocus().

Related

How to write a custom debugging helper for nlohmann::basic_json?

I am faced with the task of writing a simple debug helper for Qt Creator 4.13.1 / Qt 5.12.5 / MSVC 2017 compiler for the C++ JSON implementation nlohmann::basic_json (https://github.com/nlohmann/json).
An object of nlohmann::basic_json can contain the contents of a single JSON data type (null, boolean, number, string, array, object) at a time.
There's a dump() member function which can be used to output the current content formatted as a std::string regardless of the current data type. I always want to use this function.
What I've done so far:
I've looked at https://doc.qt.io/qtcreator/creator-debugging-helpers.html, as well as at the given example files (qttypes.py, stdtypes.py...).
I made a copy of the file personaltypes.py and told Qt Creator about its existence at
Tools / Options / Debugger / Locals & Expressions / Extra Debugging Helpers
The following code works and displays a "Hello World" in the debugger window for nlohmann::basic_json objects.
import dumper
def qdump__nlohmann__basic_json(d, value):
d.putNumChild(0)
d.putValue("Hello World")
Unfortunately, despite the documentation, I have no idea how to proceed from here on.
I still have absolutely no clue how to correctly call basic_json's dump() function with the dumper from Python (e.g. with d.putCallItem ?).
I also have no starting point how to format the returned std::string so that it is finally displayed in the debugger window.
I imagined something like this, but it doesn't work.
d.putValue("data")
d.putNumChild(1)
d.putCallItem('dump', '#std::string', value, 'dump')
I hope someone can give me a little clue so that I can continue thinking in the right direction.
For example, can I call qdump__std__string from stdtypes.py myself to interpret the std::string?

Setting NSSpeechSynthesizer mode from Python

I am using PyObjC bindings to try to get a spoken sound file from phonemes.
I figured out that I can turn speech into sound as follows:
import AppKit
ss = AppKit.NSSpeechSynthesizer.alloc().init()
ss.setVoice_('com.apple.speech.synthesis.voice.Alex')
ss.startSpeakingString_toURL_("Hello", AppKit.NSURL.fileURLWithPath_("hello.aiff"))
# then wait until ve.isSpeaking() returns False
Next for greater control I'd like to turn the text first into phonemes, and then speak them.
phonemes = ss.phonemesFromText_("Hello")
But now I'm stuck, because I know from the docs that to get startSpeakingString to accept phonemes as input, you first need to set NSSpeechSynthesizer.SpeechPropertyKey.Mode to "phoneme". And I think I'm supposed to use setObject_forProperty_error_ to set that.
There are two things I don't understand:
Where is NSSpeechSynthesizer.SpeechPropertyKey.Mode in PyObjC? I grepped the entire PyObjC directory and SpeechPropertyKey is not mentioned anywhere.
How do I use setObject_forProperty_error_ to set it? I think based on the docs that the first argument is the value to set (although it's called just "an object", so True in this case?), and the second is the key (would be phoneme in this case?), and finally there is an error callback. But I'm not sure how I'd pass those arguments in Python.
Where is NSSpeechSynthesizer.SpeechPropertyKey.Mode in PyObjC?
Nowhere.
How do I use setObject_forProperty_error_ to set it?
ss.setObject_forProperty_error_("PHON", "inpt", None)
"PHON" is the same as NSSpeechSynthesizer.SpeechPropertyKey.Mode.phoneme
"inpt" is the same as NSSpeechSynthesizer.SpeechPropertyKey.inputMode
It seems these are not defined anywhere in PyObjC, but I found them by firing up XCode and writing a short Swift snippet:
import Foundation
import AppKit
let synth = NSSpeechSynthesizer()
let x = NSSpeechSynthesizer.SpeechPropertyKey.Mode.phoneme
let y = NSSpeechSynthesizer.SpeechPropertyKey.inputMode
Now looking at x and y in the debugger show that they are the strings mentioned above.
As for how to call setObject_forProperty_error_, I simply tried passing in those strings and None as the error handler, and that worked.

cannot spot the Type Error reported by the Python Shell

Hi I'm realtively new to computer science and learning to code Python. Here is a section of the code that I have trouble with:
from uagame import Window
from time import sleep
window = Window('hello',300,200)
user = window.input_string('Enter string>',0,0)
x = window.get_width() - window.get_string_width(user)
y = window.get_height() - window.get_font_height(user)
window.draw_string(user_input,x,y)
sleep(2)
window.close()
It always display a Type error and I do not know the reasons. I've run similar codes with no problem
Here is the error:
builtins.TypeError: get_font_height() takes 1 positional argument but 2 were given
Any help will be appreciated
What that means, I'm guessing, is that window.get_font_height() is a method that doesn't take an argument. Since it's window.<method name>, the first argument to get_font_height is probably going to be self! So you are passing a user to that function, which is, I'm guessing, the second argument.
Look up the documentation for uagame window.get_font_height and make sure you're using it correctly.
The guesses of the other respondents are correct: get_font_height takes only the Window object as an argument, and receives that through the normal call sequence (i.e. the window is the self argument). The font height is returned as an int.
There is no dependence whatsoever on your input string; that argument is not allowed, and that's why you got that error message. Simply remove that and call as window.get_font_height().

VIM/Python Insert-Mode-Completion Popup Menu

I would like to create a VIM insert-mode-completion popup menu, preferably directly via the python vim module but also by calling vim commands if necessary. Per my requirements, if this is possible, what do I need to know?
Requirements
Modify the menu based on input. Either recolor and replace select characters ala easymotion plugin, or completely replace content, possibly resulting in a change of size.
Customizable navigation bindings, example:
j/k for vertical navigation (partial redraw)
h/l for category navigation/refinement (full redraw)
others as category/relationship shortcuts (full)
others as source cycling (full)
easymotion-style bindings (partial)
others for related functionality (none)
optionally, in lieu of the above bindings, a fuzzy filtering mode (capture all input) (full)
Hook to run action when menu is destroyed
Ability to replace previous word if menu item selected (easily done in normal mode... but, is there a better approach than calling :norm?)
Once again, I need to know if any of this is possible. If so, please provide specific documentation regarding the required capabilities, APIs, or functions. Well, enough to get me started.
If important, I'm not sure of the interface specifics yet but the menu itself may need to be quite large to accommodate the content.
Edit:
I haven't tried anything; rather I'm asking what I should read or know to implement the vim-specific functionality I need. All I now have is python code that accepts a sentence and a word in that sentence, determines the POS, lemmatises the word, and provides synonyms.
It should be clear by now this is a vim plugin providing thesaurus-like functionality, augmenting vim's built-in CTRL_X-CTRL_T functionality. Unfortunately synonymy is a complicated hierarchy, for example see thesaurus.com or wordnet. Below is a tree of the synonym selection process. To provide useful thesaurus functionality I would need to navigate this tree within the insert-mode-completion popup menu. By automatically inferring the POS the first step can be skipped, and of course it makes sense to initially merge and display all sense synonyms irrespective of relationship. However, to determine the POS I need access to the entire sentence, and I still need to be able to navigate a sense selection menu. I also want to be able to provide scratch buffer detailing word definitions and example sentences for the currently highlighted popup menu entry. Hence the necessity for a hook; to destroy the buffer when the menu is destroyed. All the other keybindings I've described would be conveniences to, for example, filter by relationship, open the informational scratch buffer, or switch POS.
POS Sense Relationship Synonym
N -> Sense 1 -> Relationship 1 -> Synonym 1
Synonym 2
...
Synonym n
-> Relationship 2 -> Synonym 1
...
Synonym n
-> Relationship 3 -> Synonym 1
...
Synonym n
Sense 2 -> Relationship 1 -> ...
Sense 3 -> Relationship 2 -> ...
V -> Sense 1 -> ...
A -> ...
Insert completion popup menus are great because they preserve context: surrounding text doesn't change, remains (mostly) visible, and windows aren't resized. I could provide the functionality I need in a separate buffer (such as a unite plugin), however I'd rather not.
After reading :h complete-functions:
If refresh="alway", complete-functions will be re-invoked each time leading text is changed. The purpose is to refine the matches, however this has little meaning for synonym-matching, where the word is already complete and instead will just be replaced. Aside from this, insert-completion popup menus only provide minimal key mappings: <CTRL-H>, CTRL-L>, <CTRL-Y>, <CTRL-E>, etc. Additional mappings can be added using pumvisible(), however such mappings affect all popup menus, and so would not be applicable. Of course I could use <expr> to check a global variable such as g:popup-menu-is-thesaurus, but this approach is basically a heap of hacks. For example, to display a new category in the menu, I could do something like:
:call Thesaurus#BindKey("h","w:Thesaurus#CategoryUp")
:call Thesaurus#BindKey("i","w:Thesaurus#InsertMode")
with:
function! Thesaurus#BindKey(key, function)
inoremap <expr> a:key a:function
endfunction
function! Thesaurus#CategoryUp()
if !b:popup-menu-is-thesaurus
return v:char
let b:thesaurus-category-index -= 1
endfunction
function! Thesaurus#InsertMode()
if !b:popup-menu-is-thesaurus
return v:char
let b:thesaurus-mode = "insert"
endfunction
function! Thesaurus#CompleteFunc(findstart, base)
if a:findstart
...
else
if b:thesaurus-mode = "insert"
return Thesaurus#FuzzyMatch(base)
else
return Thesaurus#Redraw()
endif
endif
endfunction
function! Thesaurus#Redraw()
...
endfunction
* Obviously I'm not very good with VimL. Also, am I using v:char correctly?
Of course I have no idea how to replace the previous word once an entry is selected, since the only way to enable fuzzy matching is to have a:base be empty.
Edit2: And how in the world do I get my completion-function triggered, preferably via the standard thesaurus-style completion shortcut, i_CTRL-X_CTRL-T? I don't want to lose my custom completions (omni and user-defined completion), and since the popup displays in the current buffer, unlike FuzzyFinder I can't override omnifunc.
Perhaps the ideal approach would be to have full control of the menu-drawing functionality to build the popup from scratch, and fake a new insert-completion popup menu mode using plugins such as tinymode, tinykeymap or submode.
Please keep in mind that the insert-mode completion popup menu is for completing matches e.g. offering foobar and foomatic when you type foo and trigger completion. There is no generic insert-mode menu with arbitrary actions, and it's probably a bad idea to implement such. That said, some plugins (e.g. FuzzyFinder) mis-use insert-mode completion menus for a dynamic choice selector (in a scratch buffer, so what get's completed is discarded there).
You'll find the full specification and an example at :help complete-function. If that doesn't satisfy you / leaves open questions, that's a sure sign that you're trying to use it for something it wasn't meant for.
Modify the menu based on input.
With each typed key, your 'completefunc' will be re-invoked, and it can offer a (reduced) set of matches.
Customizable navigation bindings
Bad idea. The user should customize this for all completions (using :imap <expr> with pumvisible() conditionals).
Hook to run action when menu is destroyed
The CompleteDone event has been added in recent Vim versions, but usually the only action should be "insert the match", which gets done automatically.
Ability to replace previous word if menu item selected
On the first invocation of your 'completefunc', your function can specify the base column, i.e. where the completion matches will start.

python drag drop init issues

I'm confused as to how I would implement a drag and drop ability for a window and then have the url appear in the textbox.
I've updated where I am stuck at
class controller(NSWindow):
#File to encode or decode
form_file = IBOutlet()
mainWindow = IBOutlet()
#drag and drop ability
def awakeFromNib(self):
self.registerForDraggedTypes_([NSFilenamesPboardType, None])
print 'registerd drag type'
def draggingEntered_(self, sender):
print 'dragging entered doctor who'
pboard = sender.draggingPasteboard()
types = pboard.types()
opType = NSDragOperationNone
if NSFilenamesPboardType in types:
opType = NSDragOperationCopy
return opType
def performDragOperation_(self,sender):
print 'preform drag operation'
pboard = sender.draggingPasteboard()
successful = False
if NSFilenamesPboardType in pboard.types():
print 'my actions finally working'
fileAStr = pboard.propertyListForType_(NSFilenamesPboardType)[0]
print type(fileAStr.encode('utf-8'))
successful = True
print self.form_file
return successful
I can drop the file but I am unable to refrence the form_file outlet from inside of the performDragOperation function. As you can see I am attempting to print it but it returns a NoneType error.
(reason '<type 'exceptions.TypeError'>: 'NoneType' object is not callable') was raised during a dragging session
I believe your problem here was that something earlier in the Responder Chain was handling -[draggingEntered:] and rejecting the drag, before your window could get to it.
For a typical AppKit app, before getting to the window, an action message goes to the First Responder from the NIB, and anything hooked onto the back of it, then the innermost view and its delegate, then all of its ancestor views and their delegates. So if, for example, you have a text edit view that handles drag messages, and you drag over that view, the window won't see it.
Anyway, there are lots of ways to debug this, but the simplest one is to just have each method iterate the nextResponder() chain from self, printing (or logging.logging or NSLogging) the result. Then you can see who you're blocking.
Since there were a bunch of other issues we talked about in the comments, I'm not sure if this was the one that actually solved your problem. But one thing in particular to bring up:
I don't think PyObjC was part of the problem here. When the Cocoa runtime sends an ObjC message like -[draggingEntered:] to a PyObjC object, the PyObjC runtime handles that by looking for a draggingEntered_ method and converting it magically. (Well, I say magic, but it's simple science. Also, because it's sonic, it doesn't do wood.) You need #IBAction in the same places an ObjC program would need (IBAction), which are documented pretty well in the Cocoa documentation.
Meanwhile, one general-purpose debugging tip for PyObjC code (or just about any other event-loop-based or otherwise non-linear code). When you get an error like this:
(reason '<type 'exceptions.TypeError'>: 'NoneType' object is not callable') was raised during a dragging session
It's hard to figure out what exactly went wrong. But you can handle the exception inside the function that raised, and get all the information you want. You can wrap a try/except around each line to figure out which line raised, you can print the whole traceback instead of just the summary, etc.

Categories