Здравствуйте.
Хочу написать программу для Linux, а конкретно для Kubuntu. Вопросы такие:
1) Какой язык использовать? Из знакомых мне языков, в винде я писал на Delphi и редко на C++. Delphi знаю сравнительно неплохо. Если использовать VCL, то там вообще всё просто. Установил Lazarus. Грубо говоря, это хак Delphi 7. Кинул на форму shape и таймер и сделал, чтобы shape перемещался по форме. Это совсем просто. Компоненты VCL создаются автоматически. Всё как в Delphi. Но.... вопрос 2
2) Как взаимодействовать с KDE? Например, найти хендл окна, свернуть/развернуть/закрыть окно, получить/изменить имя окна. В общем, банальные функции взаимодействия (чтобы с самого простого начать изучать API Linux'а).
Например, в мастдае для этого есть функции типа CreateWindow, DestroyWindow, GetWindowPos, SendMessage и т.д. А какие функции взаимодействия есть у KDE?
Еще например: как получить список папок в указанной папке, типа /home/god/pictures?
Что для этого нужно? Есть ли какой-то справочник или how to по функциям? гугл не помогает. находит только функции мастдая
Жарь на QT, что тут думать то?
QT крашится, когда я жму кнопку "design". Я думаю, что мне пока нужен язык с синтаксисом, как у Lazarus/Delphi, так как с ним я больше знаком, а QT вижу впервые, хоть там и С. Но, всё-таки, где посмотреть функции взаимодействия или исходники программ на лазарусе (для наглядности)?
Для разработки под линух лучше не привязываться к конкретной DE, чтобы работало под любым дистрибутивом.
Как правило, для оконного инструментария выбирают одну из набора библиотек: Qt, GTK, SDL, GLFW и т.д.
Если выберете Qt, то советую обратить внимание на пятую версию и QtQuick - избавит от лишнего гемора с плюсами в интерфейсной части.
А если хорошо знаете Паскаль/Lazarus, скачайте и поизучайте исходники Double Commander'а:
apt-get source doublecmd
Там найдете ответы на все вышеприведенные вопросы в примерах =)
Да, Delphi/Lazarus ( он же паскаль) я знаю лучше.
спасибо, посмотрю DC
Скачал исходники DC. Лазарус пишет, что нужны дополнительные пакеты. Где их взять?
Я бы наверное попытался разобраться с Qt. Все таки программы написанные на Qt могут работать на windows, linux и помойму уже на андроиде. Если тебе нужно работать внутри своего приложения с окнами то в Qt это делается без всякого гемороя + в Qt очень хорошая справка. Еще очень удобная система сигналов и слотов. Также есть события.
Вот пример простейшей программы которая создаст 2 окна. Одно окно будет содержать Просто текст "Hello, world", а вторая кнопку. При нажатии на кнопку программа закроется
#include <QApplication>
#include <QLabel>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l("Hello, world");
l.resize(100,100);
QPushButton p("Quit");
l.show();
p.show();
QObject::connect(&p, SIGNAL(clicked()), &a, SLOT(quit()));
return a.exec();
}
Только что поставил Qt creator(с оф. сайта) работает нормально.
Попытался я эту программу скомпилировать и запустить на своем телефоне под Андроидом.. Работает ). Правда вывелась на экран только огромная кнопка Quit. Ну это наверное особенность мобильной платформы. На экране может быть только один виджет.
я ставил из репозитория (muon center). Он крашится при нажатии кнопки "design". p.s. Kubuntu стоит на VirtualBox, если что.
А можно где-то посмотреть еще примеры исходников для qt? а еще лучше учебник такого вида http://rus-linux.net/MyLDP/BOOKS/ProgrX/xwin-contents.shtml
под "взаимодействием" я имел ввиду, как найти хендл чужого окна и получить его имя/переименовать/свернуть/развернуть/закрыть. Чтобы понять принципы работы окон. Или просто проверить, запущена ли моя программа, чтобы не дать ей запуститься дважды.
В Qt Можно это сделать при помощи класса QDir.
#include <QApplication>
#include <QDir>
#include <QStringList>
#include <QFileInfoList>
#include <QFileInfo>
#include <QTextStream>
#include <QListWidget>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QDir dir("/");
QListWidget dirls;
for(QFileInfo i : dir.entryInfoList(QDir::Dirs))
dirls.addItem(i.absoluteFilePath());
dirls.show();
return app.exec();
}
Да, мне стоит поизучать QT. Выглядит довольно просто.
Но мне очень нужна программа для фиксации щелчка мыши. Есть ли примеры, демонстрирующие использование функций XGrabButton()/XGrabPointer()? Извините, что не в тему, просто очень нужно.
Я не программист) мало чего помню уже.. Можно в Qt обрабатывать события мышки.. Если мне память не изменяет нужно создать класс наследовать его от QWidget и переопределить функцию обработчика событий mouseReleaseEvent(QMouseEvent * event). event будет содержать информацию о координатах, какая кнопка была нажата итд.. Но это действует только в пределах приложения.. А я понимаю вам нужно перехватывать все нажатия независимо в каком приложении они сделаны.. Таким я не занимался =).
Вы правильно понимаете :) Гугл выдает, что это делается при помощи функций XGrab***(), но как именно - не ясно.
Если кто-то поможет, буду крайне признателен.
А по теме вроде всё ясно.
http://en.wikipedia.org/wiki/Root_window
http://tronche.com/gui/x/xlib/display/display-macros.html (DefaultRootWindow)
#include <X11/Xlib.h>
//блаблабла
Display *disp;
Window root;
disp = XOpenDisplay(NULL);
root = DefaultRootWindow(disp);
XGrabPointer(disp, root, False, ButtonPressMask | ButtonReleaseMask |
PointerMotionMask, GrabModeAsync, GrabModeAsync, None,
None, CurrentTime);
XEvent ev;
while (1) {
XNextEvent(disp, &ev);
//блаблабла
}
//блаблабла
А события мыши ловить, как обычно? Т.е. те же, что приходят при движении по своему окну?
Да, грабятся все события с рутового окна.
Всем большое спасибо! Буду пробовать.
не удаляйте тему
Нашел такой код
#include <stdio.h>
#include <assert.h>
#include <X11/Xlib.h>
int main(void)
{
Display *d;
Window root;
d = XOpenDisplay(NULL);
assert(d);
root = DefaultRootWindow(d);
XGrabPointer(d, root, False, ButtonPressMask | ButtonReleaseMask |
PointerMotionMask, GrabModeAsync, GrabModeAsync, None,
None, CurrentTime);
XEvent ev;
while (1) {
XNextEvent(d, &ev);
switch (ev.type) {
case ButtonPress:
printf("Button press event!\n");
break;
case ButtonRelease:
printf("Button release event!\n");
break;
case MotionNotify:
printf("Motion notify event!\n");
break;
default:
printf("Unknown event...\n");
}
}
XCloseDisplay(d);
return 0;
}
Компилировать нужно с ключем -lX11. Чтобы потключить библиотеку. Если пользуетесь Qt creater в pro файл добавь LIBS += -lX11
И да.. Самое главное )) Он перехватывает событие мышки.. Так что закрыть окно программы с помощью мышки не получится ))
Своё окно или все окна? А если сделать кнопку "exit", то закроется?
Я только что создал приложение и откомпилировал его.. Эм при нажатие на кнопку мышки в консоль выводит что я нажал на кнопку и все, дальше он это событие не передает )) Врядли это то что вы искали )) попробуйте откомпилировать приложение сами
Создайте main.c и вставте в него код программы а потом а потом откомпилируйте его gcc main.c -o x11mouse -lX11
Для того чтобы выйти из приложения поможет "ctrl+Esc" с помощью клавиатуры выберете программу и нажмите del
может, это из-за break?
Нет, break прерывает тело цикла и перебрасывает на проверку условия.
В теории, событие можно попробовать передать дальше через XSendEvent()
не получается
Я понял, как использовать XSendEvent() и он работает!
Нужно только узнать окно под курсором мыши, чтобы передать его в XSendEvent(...,window,...,...,event).
Но как узнать окно, над котором находится мышь?
В гугле 3 силка
СИНТАКСИС
Status XSendEvent(display, w, propagate, event_mask, event_send)
Display *display;
Window w;
Bool propagate;
long event_mask;
XEvent *event_send;
АРГУМЕНТЫ
display - указатель на структуру, описывающую соединение с X-сервером;
w - идентификатор окна, которому предназначается событие;
propagate - флаг, влияющий на выбор получателя события;
event_mask - битовая маска события;
event_send - отправляемое событие.
Кроме указания идентификатора окна в аргументе w можно использовать следующие значения:
PointerWindow - в качестве получателя события будет выбрано окно, над которым находится графический курсор мыши;
InputFocus - в качестве получателя события будет выбрано окно, которому принадлежит фокус ввода с клавиатуры.
XSendEvent(d, pointerwindow, true, ButtonPressMask,@e);
Так чтоли?
У меня сейчас нету времени и возможности проверить.. Но тут помойму есть ошибки. В С pointerwindow и PointerWindow это разные вещи. И вместо @e наверное нужно &e.
на паскале регистр не учитывается.
я пробовал и в С (qt creator) и в лазарусе - компилится, но не работает.
Отправить комментарий