2015-12-13 8 views
12

Я создал несколько кнопок (окон) в главном окне, но клавиши вкладок и стрелок не работают. Мои исследования показали, что для C++, использование IsDialogMessage в сообщении насоса создает обходной TranslateMessage/DispatchMessage следующим образом разрешить эту функциональность:Как включить вкладку и клавиши со стрелками с помощью python win32gui

while(GetMessage(&Msg, NULL, 0, 0)) 
{ 
    if(!IsDialogMessage(g_hToolbar, &Msg)) 
    { 
     TranslateMessage(&Msg); 
     DispatchMessage(&Msg); 
    } 
} 

Однако, я использую Python и модуль win32gui к CreateWindows и Я не могу понять, как обойти обычный захват сообщения, чтобы обеспечить естественную работу с клавиатурой. Мой код похож на этот:

from win32gui import * 
from win32con import * 

window_class = WNDCLASS() 
hinst = window_class.hInstance = GetModuleHandle(None) 
window_class.lpszClassName = 'ClassName' 
window_class.style = CS_VREDRAW | CS_HREDRAW 
window_class.hCursor = LoadCursor(0, IDC_ARROW) 
window_class.hbrBackground = COLOR_WINDOW 
window_class.lpfnWndProc = {} 
classAtom = RegisterClass(window_class) 

hwnd = CreateWindow(classAtom, "", WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION 
        | WS_SYSMENU | WS_MINIMIZEBOX | WS_EX_TOPMOST | WS_CLIPSIBLINGS, 
        0, 0, 140, 100, 0, 0, GetModuleHandle(None), None) 
btn1_hwnd = CreateWindow("Button", "btn 1", WS_GROUP | WS_TABSTOP | WS_VISIBLE 
         | WS_CHILD | BS_DEFPUSHBUTTON | WS_CLIPSIBLINGS, 
         10, 10, 100, 20, hwnd, 0, GetModuleHandle(None), None) 
btn2_hwnd = CreateWindow("Button", "btn 2", WS_GROUP | WS_TABSTOP | WS_VISIBLE 
         | WS_CHILD | BS_DEFPUSHBUTTON | WS_CLIPSIBLINGS, 
         10, 40, 100, 20, hwnd, 0, GetModuleHandle(None), None) 

UpdateWindow(hwnd) 
PumpMessages() 

EDIT: С помощью этого кода, окно с двумя кнопками создается, но это не представляется возможным, чтобы переместить фокус от одного к другому, хотя оба они имеют флаг WS_TABSTOP ,

Согласно MSDN IsDialogMessage specification, приведенный выше фрагмент C++ является решением.

When IsDialogMessage processes a message, it checks for keyboard messages and converts them into selections for the corresponding dialog box. For example, the TAB key, when pressed, selects the next control or group of controls, and the DOWN ARROW key, when pressed, selects the next control in a group.

Because the IsDialogMessage function performs all necessary translating and dispatching of messages, a message processed by IsDialogMessage must not be passed to the TranslateMessage or DispatchMessage function.

Так, в основном, вопрос: может IsDialogMessage быть использован с win2gui Пайтона, или есть обходной путь?

+0

@zvone вы не предоставили воспроизводимый пример - АтомомКласс не определен (большой кусок кода здесь), то ShowWindow не называется. TranslateMessage/DispatchMessage доступны в win32gui, так что же проблема? – denfromufa

+1

@denfromufa Я обновил вопрос. Обратите внимание, что PumpMessages можно заменить на цикл GetMessage/'TranslateMessage' /' DispatchMessage', но 'IsDialogMessage' отсутствует, чтобы заставить его работать. – zvone

ответ

0

Есть два ответа, короткие и длинные.

Короткий ответ, просто установите keyboard v0.6.5.

Долгий ответ: наберите короткий код клавиатуры, затем установите его.

+0

Хотя эта ссылка может ответить на вопрос, лучше включить здесь основные части ответа и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменится. –

+0

Если ссылки PyPi меняются, значит, у вас гораздо больше проблем. –

+0

Хотя эта ссылка может ответить на вопрос, ** лучше включить основные части ответа здесь ** и предоставить ссылку для справки. Ответы только на ссылку могут быть недействительными, если использовать пример кода из связанной страницы повышает значение атрибута AttributeError: «NoneType» не имеет атрибута «read_event» –

1

Я нашел пример использования CreateDialogIndirect на programcreek.com, который создает окно, подобное тому, которое задает вопрос, с работающими вкладками. Вот она, слегка модифицирована:

import win32con 
import win32gui 
import win32api 

parent_hwnd = None 
msgs = {} 
style=win32con.WS_BORDER|win32con.WS_VISIBLE|win32con.WS_CAPTION|win32con.WS_SYSMENU ## |win32con.DS_SYSMODAL 
h=win32gui.CreateDialogIndirect(
    win32api.GetModuleHandle(None), 
    [['One ugly dialog box !',(100,100,200,100),style,0], 
    ['Button','Create', win32con.IDOK, (10,10,30,20),win32con.WS_VISIBLE|win32con.WS_TABSTOP|win32con.BS_HOLLOW|win32con.BS_DEFPUSHBUTTON], 
    ['Button','Never mind', win32con.IDCANCEL, (45,10,50,20),win32con.WS_VISIBLE|win32con.WS_TABSTOP|win32con.BS_HOLLOW], 
    ['Static','Desktop name:',71,(10,40,70,10),win32con.WS_VISIBLE], 
    ['Edit','',72,(75,40,90,10),win32con.WS_VISIBLE]], 
    parent_hwnd, msgs) 

win32gui.EnableWindow(h,True) 
hcontrol = win32gui.GetDlgItem(h,72) 
win32gui.EnableWindow(hcontrol,True) 
win32gui.SetFocus(hcontrol) 
win32gui.PumpMessages() 
+0

Я не знаю, почему это работает. В чем разница? Любые объяснения приветствуются. Не стесняйтесь редактировать мой ответ с объяснением;) – zvone

+0

К сожалению, диалог не то, что я хочу. Моя реализация tkinter работает так же, как и ожидалось (даже пропускает элементы управления, которые отключены), мне просто не нравится весь багаж (файлы), связанный с tkinter, и в конечном итоге может понадобиться перейти на C++. – mjpsr11

 Смежные вопросы

  • Нет связанных вопросов^_^