PDA

View Full Version : شورت کات خروج از Qprocess



hmm
دوشنبه 27 مرداد 1393, 11:47 صبح
با سلام
بنده قصد دارم برنامه ای مانند Kcalc (ماشین حساب K) رو از درون یک برنامه QT فراخوانی کنم که طبیعتا این کار با Qprocess انجام میشه . مشکل اینجاست که میخواهم این برنامه با کلیدی مانند F10 بسته بشه ولی اینکار با روشهای installeventfilter و Qshortcut تا حالا جواب نداده ...
نکته اینجاست که اگه فوکوس روی فرم برنامه باشه با زدن F10 برنامه مورد نظر بسته میشه ولی اگه فوکوس روی برنامه مورد نظر باشه اتفاقی نمی افته .
ممنون میشم اگه راهکاری وجود داره بفرمایید.

حامد مصافی
دوشنبه 27 مرداد 1393, 12:22 عصر
https://github.com/mitei/qglobalshortcut

hmm
شنبه 08 شهریور 1393, 16:05 عصر
ممنون حامد جان
لینکی که فرستادی برای kclac بخوبی کار میکنه ...
ولی شوربختانه واقعیت اینه که من میخوام روی برنامه ی vncviewer اینکار رو انجام بدم و فکر کنم این برنامه حین اجرا تمام کلیدها رو grab میکنه و شورتکات سراسری برای این برنامه ی خاص کار نمیکنه ... نمیدونم آیا راه حلی برای حل این مشکل وجود داره یا نه مثلا اینکه قبل از اجرای vncviewer یک کلید رو استثنا کرد یا در برنامه اصلی مون الویت رو به شورکات خودمون بدیم ...؟

حامد مصافی
شنبه 08 شهریور 1393, 16:54 عصر
میشه قبل از ادامه بحث به سوالات زیر جواب بدی؟
برنامه باید به صورت کراس پلت‌فرم نوشته بشه؟ چرا به جای Qt از kdelibs استفاده نمی‌کنید؟
قراره فقط روی سکو‌های X11 اجراش کنید؟

hmm
یک شنبه 09 شهریور 1393, 14:11 عصر
سلام
1- برنامه فقط روی لینوکس و فقط روی سکوی X11 اجرا میشه
2- دلیل انتخاب Qt اینه که یک برنامه کامل با Qt الان وجود داره و فقط یک امکان جدید قراره بهش اضافه بشه که همان نمایش vncviewer با قابلیت سوییچ کردن بین دسکتاپ های مختلف با شورتکاتی مانند Scroll Lock میباشد و طبیعتا ارزش بازنویسی کل برنامه با پلتفرم دیگه وجود نداره .

منتظر ادامه بحث هستم ... ممنون

حامد مصافی
یک شنبه 09 شهریور 1393, 14:37 عصر
بحث اول:
kdelibs مجموعه کتابخانه‌هایی جهت برنامه‌نویسی برای رابط گرافیکی kde هست. این کتابخانه مستقیما بر پایه کیوت بنا شده مثلاً KDialog از QDialog مشتق شده یا KMessageBox, KAction و .... اما kde کلاس‌های دیگری هم به کتابخانه خودش اضافه کرده از اون جمله KGlobalAccel (http://api.kde.org/pykde-4.2-api/kdeui/KGlobalAccel.html) در حالت عادی این کلاس باید کار شما رو راه بندازه. مگر اینکه همونطوری که اشاره فرمودید برنامه مورد نظر شما عمل بلاکی انجام داده باشه. در این صورت می‌تونید کمی سطح پایین کار کنید مانند xhotkeys (http://www.nongnu.org/xhotkeys/) اگر این هم مشکل رو مرتفع نکرد می‌تونید در یک حلقه بافر کیبورد رو بررسی کنید. یادمه قبلاً برای نوشتن برنامه‌ای شبیه بابیلون از این روش استفاده کردم و جواب هم می‌داد. شما اسم اون برنامه vncviewer رو بفرمایید تا نگاهی بهش بندازم

بحث دوم:
libvnc (https://libvnc.github.io/success.html) کتابخانه‌ایه برای کار با vnc. از جمله نرم‌افزارهایی که ازش استفاده می‌کنند می‌تونم VirtualBox رو اسم ببرم. می‌تونید از قسمت کلاینت این لایبرری استفاده کنید.

hmm
یک شنبه 09 شهریور 1393, 15:25 عصر
سلام مجدد و تشکر فراوان
حقیقتش با xhotkeys کار نکردم امتحان میکنم و نتیجه رو میگم.
اشاره به حلقه برای چک کردن بافر کیبورد کردید. آیا وقتی فوکوس روی برنامه ی دیگری هست و کیبورد تو اون برنامه عکس العمل داره، برنامه ی والد (همون برنامه Qt) هم این بافر رو میبینه ؟ اگه جواب مثبته مثالی از این مورد دارید؟
در مورد کتابخانه libvnc هم این خدمتتون بگم که از این کتابخانه استفاده کردم ولی در این پروژه، موضوع فقط نمایش دسکتاپهای پروتکل vnc نیست و بعضی وقتا پروتکل Spice (http://www.spice-space.org/)هست که متاسفانه اون دیگه کتابخانه اش رو ندیدم. و مجبورم با Qprocess برنامه spiceclient رو اجرا کنم.

حامد مصافی
یک شنبه 09 شهریور 1393, 15:49 عصر
اشاره به حلقه برای چک کردن بافر کیبورد کردید. آیا وقتی فوکوس روی برنامه ی دیگری هست و کیبورد تو اون برنامه عکس العمل داره، برنامه ی والد (همون برنامه Qt) هم این بافر رو میبینه ؟ اگه جواب مثبته مثالی از این مورد دارید؟
این کلاس که کدش رو اینجا گذاشتم وظیفش اینه که اگر کلید‌هایی مانند Ctrl+RightButton فشرده شد پنجره اصلی رو نمایش بده. البته اون دکمه‌ها در تنظیمات ست می‌شوند.
من کل کد کلاس رو براتون گذاشتم. شما قسمت‌هایی رو که می‌خوای جدا کن

#include "translatedialog.h"
#include "translatedialogbase.h"


#include "screencapturemanager.h"


#include <QDebug>
#include <QSystemTrayIcon>
#include <QTimer>
#include <QDesktopWidget>
#include <QEventLoop>
#include <QClipboard>
#include <QMenu>
#include <QAction>
#include <QApplication>
#include <QLabel>
#include <QSettings>


#include <qvarlengtharray.h>


#include "configdialog.h"
#include "threadmanager.h"
#include "aboutdialog.h"


threadManager::threadManager(QObject *parent) : QObject(parent),
_enable(true),
_mask(0)
{
Q_INIT_RESOURCE(resource);


dialog = new translateDialogBase();
dialog->setObjectName("dialog");
dialog->setWindowFlags(Qt::WindowStaysOnTopHint);


capture = new screenCaptureManager(dialog);


createTrayIcon();


loop = new QEventLoop(this);
timer = new QTimer(this);


connect(timer, SIGNAL(timeout()),
this, SLOT(update()));


connect(dialog, SIGNAL(accepted()),
capture, SLOT(hide()));

connect(qApp->clipboard(), SIGNAL(selectionChanged()),
this, SLOT(clipboard_selectionChanged()));


QMetaObject::connectSlotsByName(this);


loadSettings();
}


threadManager::~threadManager()
{
//dialog->close();
//delete dialog;
//delete timer;
}


void threadManager::loadSettings()
{
QSettings set;


_mask = set.value("shortcut", 0).toInt();
_selectionMonitor = set.value("selectionMonitor", false).toBool();
}


void threadManager::start()
{
display = XOpenDisplay(0);
root = XRootWindow(display, 0);


timer->setInterval(50);
timer->start();


loop->exec();
}


void threadManager::stop()
{
timer->stop();
loop->exit();
}




void threadManager::clipboard_selectionChanged()
{
if(_selectionMonitor){
QString s = qApp->clipboard()->text(QClipboard::Selection);
dialog->translateWord(s);


capture->show();
dialog->exec();
capture->hide();
}
}


void threadManager::update()
{
err = XQueryPointer(display, root, &root2, &window,
&rx, &ry, &wx, &wy, &modifs);




XSelectInput(display,
QApplication::desktop()->winId(),
KeyReleaseMask | Button1MotionMask);




if(_mask && _enable && (modifs & _mask) ==_mask){
QString s = capture->captureWord();
dialog->translateWord(s);


capture->show();
dialog->exec();
capture->hide();

//QEventLoop *loopShow = new QEventLoop();
//connect(dialog, SIGNAL(rejected()),
// loopShow, SLOT(quit()));
//loopShow->exec();
}
}


void threadManager::on_enableAction_triggered()
{
_enable = enableAction->isChecked();
}


void threadManager::createTrayIcon()
{
tray = new QSystemTrayIcon(this);


QMenu *menu = new QMenu();
restoreAction = new QAction("Restore", this);
restoreAction->setObjectName("restoreAction");
QFont font = restoreAction->font();
font.setBold(true);
restoreAction->setFont(font);

enableAction = new QAction("Enable", this);
enableAction->setObjectName("enableAction");
enableAction->setCheckable(true);
enableAction->setChecked(true);


exitAction = new QAction("Exit", this);
exitAction->setObjectName("exitAction");


aboutAction = new QAction("About", this);
aboutAction->setObjectName("aboutAction");

settingsAction = new QAction("Settings", this);
settingsAction->setObjectName("settingsAction");







menu->addAction(restoreAction);
menu->addAction(enableAction);
menu->addSeparator();
menu->addAction(settingsAction);
menu->addAction(aboutAction);
menu->addSeparator();
menu->addAction(exitAction);


tray->setIcon(QIcon(":/icon/icon_48"));
tray->setContextMenu(menu);
tray->show();
}


void threadManager::on_aboutAction_triggered()
{
aboutDialog about;
about.exec();
}


void threadManager::on_restoreAction_triggered()
{
dialog->show();
dialog->raise();

QEventLoop *loopShow = new QEventLoop();
connect(dialog, SIGNAL(hidden()),
loopShow, SLOT(quit()));


loopShow->exec();
}


void threadManager::on_settingsAction_triggered()
{
configDialog config;
if(config.exec() == QDialog::Accepted)
loadSettings();
}


void threadManager::on_exitAction_triggered()
{
stop();


tray->hide();
dialog->close();


delete dialog;
close(0);


//qApp->exit();
}