Qt,多线程上下文切换与QRadioButtons
Qt, multithreading context switching with QRadioButtons
嗨,伙计们,所以我试着用我现在的方式在不同的线程之间切换,让用户在多个单选按钮之间来回切换(这里我只显示了2),当他们切换程序冻结。我想创建一个线程,停止它然后在进行单选按钮切换时创建另一个线程。我该如何做到这一点?
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
s1_thread = new skype_thread(this);
connect(s1_thread, SIGNAL(skype_sig(int)), this, SLOT(skype_change(int)));
x1_thread = new xlite_thread(this);
connect(x1_thread, SIGNAL(xlite_sig(int)), this, SLOT(xlite_change(int)));
}
void MainWindow::on_radioButton_3_toggled(bool checked) //Skype Application is checked
{
x1_thread->stop=true;
s1_thread->start();
}
void MainWindow::on_radioButton_toggled(bool checked) //X-Lite Application is checked
{
s1_thread->stop=true;
x1_thread->start();
}
skype_thread.cpp:
void skype_thread::run()
{
int err;
int skype_signal=0;
//Add programs you would like to use telephony hid here.
wchar_t skype[6] = L"Skype";
unsigned char data_usb[2];
int transfer_size = 4;
//Keyboard input event
INPUT ip;
//Device Handle
libusb_device_handle* dev;
//Initialize libusb with default device
libusb_init(NULL);
//Check whether the Red Button is meant to be a Hangup or Reject Button.
bool check_d = 0;
//Open Device VID = 0x04B4, PID = 0xE002 with the default libusb context
dev = libusb_open_device_with_vid_pid(NULL, VID, PID);
//Claim interface 3 on the device
err = libusb_claim_interface(dev, 3);
//Get first window on desktop
HWND firstwindow = FindWindowEx(NULL, NULL, NULL, NULL);
HWND window = firstwindow;
wchar_t windowtext[MAX_PATH]; //search term
//We need to get the console title in case we
//accidentally match the search word with it
//instead of the intended target window.
wchar_t consoletitle[MAX_PATH];
GetConsoleTitle(consoletitle, MAX_PATH);
//Error message for when window isn't found.
QString error_msg = NULL;
while(true){
//Check window title for a match
GetWindowText(window, windowtext, MAX_PATH);
if (wcsstr(windowtext, skype)!=NULL && wcscmp(windowtext, consoletitle)!=0) break; //search for program
window = FindWindowEx(NULL, window, NULL, NULL); //Get next window
}
while(true){
QMutex mutex;
mutex.lock();
//Differentiate the different button presses.
//Interrupt IN transfer
err = libusb_interrupt_transfer(dev, LIBUSB_ENDPOINT_IN | EP_IN, data_usb, sizeof(data_usb), &transfer_size, 1000);
if(transfer_size > 0){
if(data_usb[0]==0x02 && data_usb[1]==0x04){ //Pickup Button Payload
printf("Window found: %lsn", windowtext);
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "Alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Bring specified window into focus
SetForegroundWindow(window);
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "Pageup" key
ip.ki.wVk = 0x21; // virtual-key code for the "pageup" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Pageup" key
ip.ki.wVk = 0x21;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
check_d = 1;
}
if(data_usb[0]==0x02 && data_usb[1]==0x01 && check_d==1){ //Disconnect Button Payload
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "Alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Bring specified window into focus
SetForegroundWindow(window);
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "Pagedown" key
ip.ki.wVk = 0x22; // virtual-key code for the "pageup" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Pagedown" key
ip.ki.wVk = 0x22;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
check_d = 0;
}//end if
if(data_usb[0]==0x02 && data_usb[1]==0x01 && check_d==0){ //Reject Button Payload
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "Alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Bring specified window into focus
SetForegroundWindow(window);
//Press the "Ctrl"Key
ip.ki.wVk = 0x11; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "Pagedown" key
ip.ki.wVk = 0x22; // virtual-key code for the "pageup" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Pagedown" key
ip.ki.wVk = 0x22;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Ctrl" key
ip.ki.wVk = 0x11;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
check_d = 0;
}//end if
}//end if
if(this->stop) break;
mutex.unlock();
emit skype_sig(skype_signal);
skype_signal++;
} //end while
}
xlite_thread.cpp
void xlite_thread::run()
{
int xlite_signal=0;
int err;
//Add programs you would like to use telephony hid here.
wchar_t xlite[7] = L"X-Lite";
unsigned char data_usb[2];
int transfer_size = 4;
//Keyboard input event
INPUT ip;
//Device Handle
libusb_device_handle* dev;
//Initialize libusb with default device
libusb_init(NULL);
//Check whether the Red Button is meant to be a Hangup or Reject Button.
bool check_d = 0;
//Open Device VID = 0x04B4, PID = 0xE002 with the default libusb context
dev = libusb_open_device_with_vid_pid(NULL, VID, PID);
//Claim interface 3 on the device
err = libusb_claim_interface(dev, 3);
//Get first window on desktop
HWND firstwindow = FindWindowEx(NULL, NULL, NULL, NULL);
HWND window = firstwindow;
wchar_t windowtext[MAX_PATH]; //search term
//We need to get the console title in case we
//accidentally match the search word with it
//instead of the intended target window.
wchar_t consoletitle[MAX_PATH];
GetConsoleTitle(consoletitle, MAX_PATH);
//Error message for when window isn't found.
QString error_msg = NULL;
while(true){
//Check window title for a match
GetWindowText(window, windowtext, MAX_PATH);
if (wcsstr(windowtext, xlite)!=NULL && wcscmp(windowtext, consoletitle)!=0) break; //search for program
window = FindWindowEx(NULL, window, NULL, NULL); //Get next window
}
while(true){
QMutex mutex;
mutex.lock();
//Differentiate the different button presses.
//Interrupt IN transfer
err = libusb_interrupt_transfer(dev, LIBUSB_ENDPOINT_IN | EP_IN, data_usb, sizeof(data_usb), &transfer_size, 1000);
if(transfer_size > 0){
if(data_usb[0]==0x02 && data_usb[1]==0x04){ //Pickup Button Payload
printf("Window found: %lsn", windowtext);
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "Alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Bring specified window into focus
SetForegroundWindow(window);
//Press the "Ctrl" key
ip.ki.wVk = 0xA2; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "N" key
ip.ki.wVk = 0x4E; // virtual-key code for the "pageup" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "N" key
ip.ki.wVk = 0x4E;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Ctrl" key
ip.ki.wVk = 0xA2;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
check_d = 1;
}
if(data_usb[0]==0x02 && data_usb[1]==0x01 && check_d==1){ //Disconnect Button Payload
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "Alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Bring specified window into focus
SetForegroundWindow(window);
//Press the "Ctrl" key
ip.ki.wVk = 0xA2; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "E" key
ip.ki.wVk = 0x45; // virtual-key code for the "pageup" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "E" key
ip.ki.wVk = 0x45;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Ctrl" key
ip.ki.wVk = 0xA2;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
check_d = 0;
}//end if
if(data_usb[0]==0x02 && data_usb[1]==0x01 && check_d==0){ //Reject Button Payload
//Press the "Alt" key
ip.ki.wVk = 0x12; // virtual-key code for the "Alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "Alt" key
ip.ki.wVk = 0x12;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Bring specified window into focus
SetForegroundWindow(window);
//Press the "Ctrl" key
ip.ki.wVk = 0xA2; // virtual-key code for the "alt" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Press the "D" key
ip.ki.wVk = 0x44; // virtual-key code for the "pageup" key
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
//Release the "D" key
ip.ki.wVk = 0x44;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
//Release the "Ctrl" key
ip.ki.wVk = 0xA2;
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
SendInput(1, &ip, sizeof(INPUT));
check_d = 0;
}//end if
}//end if
if(this->stop) break;
mutex.unlock();
emit xlite_sig(xlite_signal);
xlite_signal++;
} //end while
}
您最好使用对象和计时器来重复调用对象中的插槽(该插槽被移动到工作线程)
例如:class SkypeObject: public QObject{
Q_OBJECT
slots:
void start();
void loop();
void stop();
signals:
//...
}
然后在将其移动到后台线程后触发start
和stop
插槽。在循环槽内,您将while的主体并通过QTimer触发它(或使用startTimer并继承timerEvent(QTimerEvent)
)
而且,while循环中的互斥锁实际上并没有做任何事情来防止竞争条件,除了当stop为真时退出while时发生泄漏。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- Linux的Cpp上的计时器
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在Ubuntu 16.04上安装Cilk时出现问题
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 物理键盘上的触发器按键
- 为什么不;名字在地图上是按顺序排列的吗
- 在Linux for Windows上编译C++代码时出错
- 何时在引用或唯一指针上使用移动语义
- 在c++类上调用void函数
- 在Windows上用C++裁剪HBITMAP
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- 试图在visual studio上用C++创建一个桌面应用程序
- node-gyp 在 macOS 上未正确链接库
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- PowerPC ppc64le上的Gcc Woverloaded虚拟错误
- cppcheck在const std::string[]上引发警告
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- 在WSL:configure_file上对config_file的每次调用都失败:配置文件时出现问题