2013-08-12 7 views
8

में दिखाई दे रहा है, तो मैं जानना चाहता हूं कि मेरा QMainWindow वर्तमान में दृश्यमान है और अन्य अनुप्रयोगों की दूसरी विंडो द्वारा ओवरलैप नहीं किया गया है।जांचें कि मेरा QMainWindow वर्तमान में Qt

मुझे विंडोज, लिनक्स और मैक के लिए इसे प्राप्त करने की आवश्यकता है।

+0

कृपया, लक्ष्य प्लेटफ़ॉर्म निर्दिष्ट करें। क्योंकि कोई क्रॉस-प्लेटफॉर्म तरीके नहीं हैं। –

+0

क्या आपने विरासत QWidget से 'isVisible()' की कोशिश की है? – Joum

+0

अधिकांश प्लेटफ़ॉर्म पर, "सक्रिय विंडो" अन्य सभी विंडो के ऊपर दिखाई दे रही है, लेकिन यह केवल एक पर्याप्त मानदंड है। यदि यह आपके लिए पर्याप्त है, तो 'QWidget :: isActiveWindow() 'जांचें। – arne

उत्तर

5

मैंने फोरग्राउंड या शीर्षतम खिड़की की जानकारी पढ़ने के लिए थोड़ी देर पहले एक छोटी लाइब्रेरी लिखी, मुख्य रूप से खिड़की का शीर्षक, विंडोज़, मैक ओएस एक्स और लिनक्स में। आप यहाँ स्रोत कोड पा सकते हैं: https://github.com/pcmantinker/Qt-Window-Title-Reader

मैं लिनक्स के लिए विंडोज के लिए देशी विंडोज एपीआई का उपयोग, X11 पुस्तकालयों, और मैक ओएस एक्स पर कोको

यहाँ कैसे सक्रिय विंडो पाने के लिए की एक छोटा सा नमूना है मैक ओएस एक्स में उद्देश्य सी का उपयोग कर ++:
Mac.h

/* 
    Mac/Cocoa specific code for obtaining information about the frontmost window 
*/ 

#ifndef MAC_H 
#define MAC_H 
#include <QtCore> 
#include "windowinfo.h" 

class Mac { 
public: 
    Mac(); 
    QList<WindowInfo> getActiveWindows(); 
}; 

#endif // MAC_H 

Mac.mm

/* 
    Mac/Cocoa specific code for obtaining information about the frontmost window 
*/ 

#include "mac.h" 
#include "Cocoa/Cocoa.h" 

Mac::Mac() 
{ 

} 

QList<WindowInfo> Mac::getActiveWindows() 
{ 
    QList<WindowInfo> windowTitles; 

    // get frontmost process for currently active application 
    ProcessSerialNumber psn = { 0L, 0L }; 
    OSStatus err = GetFrontProcess(&psn); 

    CFStringRef processName = NULL; 
    err = CopyProcessName(&psn, &processName); 

    NSString *pname = (NSString *)processName; 

    // loop through all application windows 
    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); 
    for (NSMutableDictionary* entry in (NSArray*)windowList) 
    { 
     NSString* ownerName = [entry objectForKey:(id)kCGWindowOwnerName]; 
     NSString *name = [entry objectForKey:@"kCGWindowName" ]; 
     NSInteger ownerPID = [[entry objectForKey:(id)kCGWindowOwnerPID] integerValue]; 
     NSInteger layer = [[entry objectForKey:@"kCGWindowLayer"] integerValue]; 
     if(layer == 0) 
     { 
      if([ownerName isEqualToString:pname]) 
      { 
       NSRange range; 
       range.location = 0; 
       range.length = [ownerName length]; 

       unichar *chars = new unichar[range.length]; 
       [ownerName getCharacters:chars range:range]; 
       QString owner = QString::fromUtf16(chars, range.length); 

       range.length = [name length]; 

       chars = new unichar[range.length]; 
       [name getCharacters:chars range:range]; 
       QString windowTitle = QString::fromUtf16(chars, range.length); 
       delete[] chars; 

       long pid = (long)ownerPID; 

       WindowInfo wi; 
       wi.setProcessName(owner); 
       wi.setWindowTitle(windowTitle); 
       wi.setPID(pid); 
       windowTitles.append(wi); 
      } 
     } 
    } 
    CFRelease(windowList); 
    CFRelease(processName); 

    return windowTitles; 
} 

कृपया ध्यान दें कि कोको में, केवल शीर्षतम विंडो प्राप्त करने का कोई सीधा तरीका नहीं है। आप जो चाहते हैं उसे ढूंढने के लिए आप उनके माध्यम से खिड़कियों और लूप का संग्रह प्राप्त करते हैं।
win.h

/* 
    Windows API specific code for obtaining information about the frontmost window 
*/ 

#ifndef WIN_H 
#define WIN_H 
#include <QtCore> 
#include "qt_windows.h" 
#include "psapi.h" 
#include "windowinfo.h" 

class win : public QObject 
{ 
    Q_OBJECT 

public: 
    win(); 
    QList<WindowInfo> getActiveWindows(); 

private: 
    TCHAR buf[255]; 
}; 

#endif // WIN_H 

win.cpp

#include "win.h" 

win::win() 
{ 
} 

QList<WindowInfo> win::getActiveWindows() 
{ 
    QList<WindowInfo> windowTitles; 
    HWND foregroundWindow = GetForegroundWindow(); 
    DWORD* processID = new DWORD; 
    GetWindowText(foregroundWindow, buf, 255); 
    GetWindowThreadProcessId(foregroundWindow, processID); 
    DWORD p = *processID; 
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | 
            PROCESS_VM_READ, 
            FALSE, p); 
    TCHAR szProcessName[MAX_PATH]; 

    if (NULL != hProcess) 
    { 
     HMODULE hMod; 
     DWORD cbNeeded; 

     if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), 
           &cbNeeded)) 
     { 
      GetModuleBaseName(hProcess, hMod, szProcessName, 
           sizeof(szProcessName)/sizeof(TCHAR)); 
     } 
    } 
    CloseHandle(hProcess); 
    long pid = (long)p; 
    QString windowTitle, processName; 
#ifdef UNICODE 
    windowTitle = QString::fromUtf16((ushort*)buf); 
    processName = QString::fromUtf16((ushort*)szProcessName); 
#else 
    windowTitle = QString::fromLocal8Bit(buf); 
    processName = QString::fromLocal8Bit(szProcessName); 
#endif 

    WindowInfo wi; 
    wi.setPID(pid); 
    wi.setWindowTitle(windowTitle); 
    wi.setProcessName(processName); 
    windowTitles.append(wi); 
    return windowTitles; 
} 

यहाँ लिनक्स/X11 के लिए कोड है::
linux_x11
यहाँ Windows API के लिए कोड है। एच

/* 
    Linux/X11 specific code for obtaining information about the frontmost window 
*/ 

#ifndef LINUX_X11_H 
#define LINUX_X11_H 

#include <QtCore> 
#include <X11/X.h> 
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 
#include <X11/Xatom.h> 
#include "windowinfo.h" 

class linux_x11 
{ 
public: 
    linux_x11(); 
    QList<WindowInfo> getActiveWindows(); 

private: 
    Window* active(Display *disp, unsigned long *len); 
    char *name (Display *disp, Window win); 
    int *pid(Display *disp, Window win); 
    QString processName(long pid); 
}; 

#endif // LINUX_X11_H 

linux_x11.cpp

/* 
    Linux/X11 specific code for obtaining information about the frontmost window 
*/ 

#include "linux_x11.h" 
#include <sstream> 
#include <stdlib.h> 
#include <stdio.h> 

linux_x11::linux_x11() 
{ 
} 

/** 
    * Returns the window name for a specific window on a display 
***/ 
char *linux_x11::name (Display *disp, Window win) { 
    Atom prop = XInternAtom(disp,"WM_NAME",False), type; 
    int form; 
    unsigned long remain, len; 
    unsigned char *list; 

    if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType, &type,&form,&len,&remain,&list) != Success) 
     return NULL; 

    return (char*)list; 
} 

/** 
    * Returns the pid for a specific window on a display 
***/ 
int* linux_x11::pid(Display *disp, Window win) { 
    Atom prop = XInternAtom(disp,"_NET_WM_PID",False), type; 
    int form; 
    unsigned long remain, len; 
    unsigned char *list; 

    if (XGetWindowProperty(disp,win,prop,0,1024,False,AnyPropertyType, &type,&form,&len,&remain,&list) != Success) 
     return NULL; 

    return (int*)list; 
} 

/** 
    * Returns the active window on a specific display 
***/ 
Window * linux_x11::active (Display *disp, unsigned long *len) { 
    Atom prop = XInternAtom(disp,"_NET_ACTIVE_WINDOW",False), type; 
    int form; 
    unsigned long remain; 
    unsigned char *list; 

    if (XGetWindowProperty(disp,XDefaultRootWindow(disp),prop,0,1024,False,XA_WINDOW, &type,&form,len,&remain,&list) != Success) 
     return NULL; 

    return (Window*)list; 
} 

/** 
    * Returns process name from pid (processes output from /proc/<pid>/status) 
***/ 
QString linux_x11::processName(long pid) 
{ 
    // construct command string 
    QString command = "cat /proc/" + QString("%1").arg(pid) + "/status"; 
    // capture output in a FILE pointer returned from popen 
    FILE * output = popen(command.toStdString().c_str(), "r"); 
    // initialize a buffer for storing the first line of the output 
    char buffer[1024]; 
    // put the contents of the buffer into a QString 
    QString line = QString::fromUtf8(fgets(buffer, sizeof(buffer), output)); 
    // close the process pipe 
    pclose(output); 
    // take right substring of line returned to get process name 
    return line.right(line.length() - 6).replace("\n", ""); 
} 

QList<WindowInfo> linux_x11::getActiveWindows() 
{ 
    QList<WindowInfo> windowTitles; 
    unsigned long len; 
    Display *disp = XOpenDisplay(NULL); 
    Window *list; 
    char *n; 
    int* p; 

    list = (Window*)active(disp,&len); 
    if((int)len > 0) 
    { 
     for (int i=0;i<(int)len;i++) { 
      n = name(disp,list[i]); 
      p = pid(disp, list[i]); 
      long p_id = 0; 
      QString pName; 
      QString windowTitle; 

      if(p!=NULL) 
      { 
       p_id = *p; // dereference pointer for obtaining pid 
       pName = processName(p_id); 
      } 

      if(n!=NULL) 
       windowTitle = QString::fromUtf8(n); 

      WindowInfo wi; 
      wi.setWindowTitle(windowTitle); 
      wi.setProcessName(pName); 
      wi.setPID(p_id); 
      windowTitles.append(wi); 
      delete n; 
      delete p; 
     } 
    } 
    delete list; 
    XCloseDisplay (disp); 
    return windowTitles; 
} 

X11 कोड काफी बदसूरत और मुश्किल समझने के लिए प्राप्त कर सकते हैं, लेकिन यह आपके लिए प्रारंभ करने चाहिए। यह काफी समय से रहा है क्योंकि मैंने सीधे एक्स 11 के साथ निपटाया है, इसलिए मैं आपको बिल्कुल नहीं बता सकता कि प्रत्येक सहायक विधि क्या करती है।

मैं कोड को सारणी देता हूं कि कोड के प्रत्येक प्लेटफॉर्म विशिष्ट टुकड़े में एक ही विधि हस्ताक्षर होता है। फिर मैं जांचता हूं कि यह मैक ओएस एक्स, विंडोज, या लिनक्स पर संकलित किया गया था और सही कक्षाओं को तुरंत चालू करता है। यह इस प्रकार से सभी एक साथ बंधे है:

#include "windowtitlereader.h" 

WindowTitleReader::WindowTitleReader() 
{ 
    qDebug() << "WindowTitleReader::WindowTitleReader()"; 
    // refresh window reading every 10ms 
    timer = new QTimer(this); 
    timer->setInterval(10); 
    timer->start(); 
    connect(timer, SIGNAL(timeout()), this, SLOT(getWindowTitle())); 
} 

WindowTitleReader::~WindowTitleReader() 
{ 
    delete timer; 
    delete m_pid; 
    delete m_processName; 
} 
void WindowTitleReader::getWindowTitle() 
{ 
    qDebug() << "WindowTitleReader::getWindowTitle()"; 
#ifdef Q_WS_WIN 
    win w; 
    m_activeWindows = w.getActiveWindows(); 
#endif 

#ifdef Q_WS_MACX 
    Mac m; 
    m_activeWindows = m.getActiveWindows(); 
#endif 

#ifdef Q_WS_X11 
    linux_x11 l; 
    m_activeWindows = l.getActiveWindows(); 
#endif 
    for(int i = 0; i < m_activeWindows.count(); i++) 
     qDebug() << "PID: " << m_activeWindows[i].getPID() << " Process Name: " << m_activeWindows[i].getProcessName() << " Window Title: " << m_activeWindows[i].getWindowTitle(); 
} 

आप अगर आप चाहते हैं एक धीमी ताज़ा दर को ताज़ा दर को बदल सकते हैं, लेकिन मैं अद्यतन हर 10ms चल रहा हूँ खिड़की ध्यान केंद्रित पर एक के पास वास्तविक समय अद्यतन प्राप्त करने के लिए।

मैंने मुख्य रूप से वेब ब्राउज़र और वीडियो गेम के विंडो शीर्षक को पढ़ने के लिए इस पुस्तकालय को लिखा है, इसलिए मुझे अनुमान लगाया जा सकता है कि लोग अपने कंप्यूटर पर कितने समय तक खेल खेलते हैं। मैंने इसे एक गेम प्ले मीट्रिक ऐप के हिस्से के रूप में लिखा है जिसे मैं बना रहा हूं।

संबंधित मुद्दे