'Embedd selenium browser in pyqt5 application

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By

chrome_options = webdriver.ChromeOptions()
s=Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=s,options=chrome_options,service_log_path='NUL')
#driver.get("http://www.stackoverflow.com")
original_window = driver.current_window_handle
print(original_window)

The output of the following code is:

  1. Open instantly google chrom in url: www.stackoverflow.com
  2. Prints the following in the console:


====== WebDriver manager ======
Current google-chrome version is 96.0.4664
Get LATEST chromedriver version for 96.0.4664 google-chrome
Driver [C:/Users/Χρήστος Παππάς/.wdm/drivers/chromedriver/win32/96.0.4664.45/chromedriver.exe] found in cache

DevTools listening on ws://127.0.0.1:64846/devtools/browser/fe12038b-ecd2-4c70-8cf3-ab0a8aeadbc3
CDwindow-1B93BAC67BF5856846B6207B11EF4F1E

where CDwindow-1B93BAC67BF5856846B6207B11EF4F1E is the driver.current_window_handle value.

So i have problem determine the Window id of selenium browser.

If this value was a int number then i could use it as input in fromWinId method of QWindow qt5 class.

So how can import selenium browser instead of QWebEngine and QWebKit in a pyqt5 application?

Please answer for a Arch-Linux based plattform support (so win32gui based answer would not be accepted).

Edit: Posible solution:

I realized that pywin32 library is available in msys2 platform. So i make something like:

from PyQt5 import QtCore, QtGui, QtWidgets
import win32gui
import win32con
import winxpgui
import win32api
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import time
import ctypes
user32 = ctypes.windll.user32
width,height = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        #self.verticalLayout.addWidget(self.frame)
        MainWindow.setCentralWidget(self.centralwidget)
        
        
        self.chrome_options = Options()
        self.chrome_options.add_argument("disable-infobars")
        #self.chrome_options.add_argument("--window-size=0,0")
        self.chrome_options.add_argument("--kiosk")
        self.chrome_options.add_argument("--window-size="+str(int(2*width))+","+str(int(2*height)))
        self.chrome_options.add_argument("--window-position=-10,-10")
        self.chrome_options.add_argument("--app=http://www.in.gr/"); 
        self.s=Service(ChromeDriverManager().install())
        
        self.driver = webdriver.Chrome(service=self.s,options=self.chrome_options,service_log_path='NUL')
        self.driver.get("http://www.in.gr")
        time.sleep(0.5)
        

        self.hwnd = 0
        self.tries = 30
        self.total_tries = 0
        while(self.hwnd==0 and self.total_tries<=self.tries):
            try:
                win32gui.EnumWindows(self.hwnd_method, None)
                #win32gui.SetWindowLong (self.hwnd, win32con.GWL_EXSTYLE, win32gui.GetWindowLong (self.hwnd, win32con.GWL_EXSTYLE ) | win32con.WS_EX_LAYERED )
                #winxpgui.SetLayeredWindowAttributes(self.hwnd, win32api.RGB(0,0,0), 255, win32con.LWA_ALPHA)
                self.embed_window = QtGui.QWindow.fromWinId(self.hwnd)
                self.embed_widget = QtWidgets.QWidget.createWindowContainer(self.embed_window)
                self.verticalLayout.addWidget(self.embed_widget)        
                #self.driver.execute_script("document.documentElement.requestFullscreen();")
                self.tries+= 1
                break
                time.sleep(1)
            except Exception as e:
                print(e)
                self.tries += 1
                
                
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        
            
    def hwnd_method(self, hwnd, ctx):
        window_title = win32gui.GetWindowText(hwnd)
        if "in.gr" in window_title.lower():
            self.hwnd = hwnd
            '''        
            old_style = win32gui.GetWindowLong(hwnd, -16)
            # building the new style(old style AND NOT Maximize AND NOT Minimize)
            new_style = old_style & ~win32con.WS_MAXIMIZEBOX & ~win32con.WS_MINIMIZEBOX
            # setting new style
            win32gui.SetWindowLong(hwnd, -16, new_style)
            # updating non - client area
            win32gui.SetWindowPos(hwnd, 0, 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_NOZORDER | win32con.SWP_FRAMECHANGED)
            win32gui.UpdateWindow(hwnd)
            '''
            #win32gui.ShowWindow(hwnd , win32con.SW_HIDE)
            
            #win32gui.SetWindowLong (hwnd, win32con.GWL_EXSTYLE, win32gui.GetWindowLong (hwnd, win32con.GWL_EXSTYLE ) | win32con.WS_EX_LAYERED )
            #winxpgui.SetLayeredWindowAttributes(hwnd, win32api.RGB(0,0,0), 0, win32con.LWA_ALPHA)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Output:

In.gr web page embedded to pyqt5 application using selenium and pywin32

The only problem with the up code is that: I don't want the full screen site to be visible until the site embedded to the QMainWindow. Any possible solution?



Solution 1:[1]

You can try adding this:

self.embed_widget.setFixedHeight(600)
self.embed_widget.setFixedWidth(600)

I have a question for you. Hope you can know something about it

I have a program that embeds multiple chrome windows at once. But the error started happening when I embed from 2nd browser.

I can click buttons but can't type anywhere in the previously opened embedded window. The same will happen when I adjust the embed window size

Thank you for reading and I'm glad I got some help from you

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ha Luu