How to show or hide Keyboard Viewer with a keyboard shortcut?
Launch Keyboard Viewer with a Service (Improved)

You can launch the Keyboard Viewer with a shortcut by using Automator and the OS X Services functionality.

The Keyboard Viewer program lives at /System/Library/Input Methods/KeyboardViewer.app (in versions prior to Lion, it may be at /System/Library/Components/KeyboardViewer.component/Contents/SharedSupport/KeyboardViewerServer.app). You open it with a hotkey by using Automator to create a simple launcher service.


Open Automator and select Service as the type of your new document.
Set the options (at the top of the workflow area) to "Service receives no input in any application".
Add the Run AppleScript action to your workflow, and replace the text with the following lines:

if application "KeyboardViewer" is running then
    quit application "KeyboardViewer"
end if

activate application "KeyboardViewer"

-- wait until the window has been closed, then end the KeyboardViewer process
set numberOfWindows to 1
repeat until numberOfWindows = 0
    delay 5
    tell application "System Events"
        tell process "KeyboardViewer"
            set numberOfWindows to count windows
        end tell
    end tell
end repeat
quit application "KeyboardViewer"

Save with a name like "Open Keyboard Viewer", then open Keyboard Preferences to the Keyboard Shortcuts tab. Select Services in the left pane and scroll to the bottom, where you should see the name of your Service under the General Section.
Make sure the box is checked to enable it, then select it and click add shortcut to set a hotkey.
After setting the hotkey, open the Services menu in any application (i.e. Finder > Services), then close it. For some reason my hot key didn't work until I did this.


A couple notes:


The script requires that you check the Enable access for assistive devices box in the Universal Access preference pane.
Closing the Keyboard Viewer window doesn't actually quit the application, and as Lri points out, it can be a bit of a resource hog, so the repeat loop checks every 5 seconds if Keyboard Viewer has any open windows, and if not, quits the process.
If you're running a pre-Lion OS, you may need to replace the instances of KeyboardViewer with KeyboardViewerServer. I don't have anything pre-Lion handy to test this (if someone else could report back in the comments, that would be great.
Because the script loops until the Keyboard Viewer is closed, the Automator spinning gear icon will show in the menu bar until it closes.